잊지말자 this의 binding

pengooseDev·2023년 3월 5일
0

Axios 객체를 구현하는 과정에서 private field인 this.#auth의 참조가 실행되지 않았다.
Class를 오랜만에 사용하다보니 콜백함수로 넘어가는 함수는 this를 명시적으로 바인딩해주지 않는다면 this가 전역객체에 바인딩되는 것을 잊고 위처럼 사고를 진행했기 때문이다.

2번에서 넘어가는 콜백함수는 콜스택에서 실행 컨텍스트가 수집될 때, this가 명시적으로 bind되어있지 않아 this는 Global(window)에 바인딩되며, 3번의 this.#auth는 undefined가 할당된다.


해결책

문득, 처음 들었던 생각은 arrowfunction을 이용하는 것이다. Private Mothod들을 arrow function으로 구현한다면, this를 생성하지 않고 scopeChaning과 같이 this를 바인딩할 수 있는 상위 객체로 거슬러 올라가 Class 객체를 참조할 것이기 때문이다.
하지만 메서드를 arrowFunction으로 구현하면 ES6 => ES5로 트랜스파일링하는 과정에서 메서드가 생성자 내부로 이동하는데, 그에 따른 sideEffect는 아래와 같다.

  • overriding
  • extends 대상에서 제외됨
  • 성능 저하
    > ref

따라서 기본적인 function으로 구현하고 ES5에서 사용하던 bind 메서드를 이용해 this를 바인딩 해주는 것이 현명해보인다.

  /* Incerceptor */
  #setInterceptor() {
    this.#instance.interceptors.request.use(
      this.#reqMiddleWare.bind(this),
      this.#reqOnError.bind(this)
    );
    this.#instance.interceptors.response.use(
      this.#resMiddleWare.bind(this),
      this.#resOnError.bind(this)
    );
  }

  /* Req */
  #reqMiddleWare(config) {
    let newConfig = config;
    if (this.#auth) newConfig = this.#setAuthReq(newConfig);

    return newConfig;
  }

0개의 댓글