왜이 파이프 중 하나는`this`를 올바르게 참조하고 다른 하나는 그렇지 않은 이유는 무엇입니까?

피터 닉 세이

나는 파이프 가능한 연산자를 만들고 있지만이 두 가지 순열의 차이점이 정확히 무엇인지 알지 못합니다. 하나는 작동하고 다른 하나는 작동하지 않습니다.

export class CrudService {

  constructor(private datastore: DatastoreService,
              private http: HttpClient) { }

  // Making the operator an attribute on the object 
  // instance allows `this.datastore` to work as expected ✅

  upsertResponse = (source: any) =>
    source.pipe(
      map((data: any) => {
        this.datastore.validate_and_upsert(data)
        return true
      })
    )
}
export class CrudService {

  constructor(private datastore: DatastoreService,
              private http: HttpClient) { }

  // Making the operator an instance method means that 
  // `this.datastore` throws an error ❌

  upsertResponse(source: any){
    return source.pipe(
      map((data: any) => {
        this.datastore.validate_and_upsert(data)
        return true
      })
    )
  }
}

this.datastore.validate_and_upsert하나 에서는 작동하지만 다른 하나 에서는 작동 하지 않는 이유는 무엇 입니까?

운영자 제안에 따라 수정 됨

이 질문은 문제의 원인에 더 가깝게 초점을 맞추기 위해 다시 표현되었습니다.

폴 크루이 트

둘 다 파이프 가능하지만 하나만 this클래스 컨텍스트에 액세스 할 수 있습니다. 나는 당신이 어느 것을 추측 할 수 있다고 생각합니다. 속성으로 만든 것. 다음을 사용하는 방법이 있습니다 .bind(this).

readonly obs$ = this.http.get().pipe(
  this.upsertResponse.bind(this)
);

upsertResponse<T>(source: Observable<T>){
  return source.pipe(
    tap((data) => this.datastore.validate_and_upsert(data)),
    mapTo(true)
  );
}

또는 전체 Observable을 소스로 사용하지만 더 이상 파이프가 아닙니다.

readonly obs$ = this.upsertResponse(this.http.get());

그러나 의견이 현명하면 질문의 속성 방식이 더 낫다고 생각합니다.

readonly upsertResponse = //...;

이렇게하면이 컨텍스트에 대해 걱정할 필요가 없으며 메서드가 유틸리티 메서드라는 것이 분명합니다.

참고로, 이벤트 리스너를 추가 할 때도 같은 일이 발생하며 익명의 화살표 함수를 사용하여 해결할 수 있습니다. 이것은 파이프 가능한 연산자에 대한 옵션이 아닙니다.
document.addEventListener('click', (event) => this.upsertEvent(event)); 

테스트 클래스에 대해 더 자세히 알아보기 :

이 수업이있는 경우 :

class TestClass {
  readonly attributeMethod = () => {
    this.executeThis()
  };

  functionMethod() {
    this.executeThis();
  }

  executeThis() {
    console.log('hi');
  }

  constructor() {
    document.addEventListener('click', this.functionMethod);
    document.addEventListener('click', this.attributeMethod);
  }
}

이것은 ES5 (안타깝게도)로 각도로 변환되어 다음과 같은 결과를 가져옵니다.

"use strict";
var TestClass = /** @class */ (function () {
    function TestClass() {
        var _this = this;
        this.attributeMethod = function () {
            _this.executeThis();
        };
        document.addEventListener('click', this.functionMethod);
        document.addEventListener('click', this.attributeMethod);
    }
    TestClass.prototype.functionMethod = function () {
        this.executeThis();
    };
    TestClass.prototype.executeThis = function () {
        console.log('hi');
    };
    return TestClass;
}());

여길 봐

당신이 볼 수 있듯이 functionMethod에 배치됩니다 prototype와는 attributeMethod내부입니다 TestClass생성자입니다. 그러나을 사용하여 클래스의에 attributeMethod액세스 할 수있는 사람 .this_this = this

따라서 functionMethod참조를 콜백 메서드로 전달할 때이 메서드는 실제로 메서드를 실행하는 모든 컨텍스트에서 호출됩니다. 같은 것은의를 참조하여 발생 attributeMethod하는 차이는 그 존재와, attributeMethod_this = this그 범위를.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관