클래스 메서드 this 바인딩

박찬욱·2023년 8월 23일
0

TIL

목록 보기
9/21
'use strict';

export default class Field {
  constructor(count) {
    this.size = 90;
    this.count = count;
    this.gameSection = document.querySelector('.game-section');
    this.gameSection.addEventListener('click', this.onClick);
  }

  setItemClick(onItemClick) {
    this.onItemClick = onItemClick;
  }

  onClick (e) {
    if (e.target.className === 'carrot') {
      e.target.remove();
      this.count--;
      this.onItemClick && this.onItemClick('carrot');
    } else if (e.target.className === 'bug') {
      this.onItemClick && this.onItemClick('bug');
    }
  };
}

주목해야할 부분은 gameSection에 이벤트 리스너를 등록하는 부분이다.
리스너 콜백함수로 클래스 내부함수인 onClick을 설정했다.

하지만 onClick은 호출되는 순간 클래스 내부의 정보를 잃어버리게된다. 왜냐하면 콜백함수로 전달되는 순간 this는 클래스의 인스턴스 정보가 아닌 이벤트 리스너 함수 자체를 가리키게 되기 때문이다.
onClick과 동일한 함수 객체가 전달되는 것이지 인스턴스 메서드의 onClick이 전달되는 것이 아니다.

때문에 this 바인딩을 해줘야한다. 방법으로는 3가지가 있다.

  1. bind 메서드
    this.onClick = this.onClick.bind(this)를 통해서 클래스가 생성할 인스턴스의 정보를 bind 메서드로 묶어주면 된다.

  2. 화살표 함수
    화살표 함수는 정적 this 바인딩이다. 즉, 화살표 함수의 this는 자신이 정의되어있는 상위 스코프의 this를 참조한다.
    밑에 코드에서 화살표함수로 한단계 감싼 이벤트 리스너 콜백함수이다.
    이렇게 되면 onClick 함수가 호출될 때 this는 인스턴스를 가리키게된다.

this.gameSection.addEventListener('click', (e)=> this.onClick(e));
  1. 메서드 화살표 함수
    클래스 메서드가 콜백함수로 전달될 일이 있다면 애초에 화살표 함수로 정의하는 것을 추천한다.
    위와 같은 이유로 콜백함수가 호출되는 시점에서 this는 자신의 상위스코프 this인 인스턴스를 가리키게된다.
'use strict';

export default class Field {
  constructor(count) {
    this.size = 90;
    this.count = count;
    this.gameSection = document.querySelector('.game-section');
    this.gameSection.addEventListener('click', this.onClick);
  }

  setItemClick(onItemClick) {
    this.onItemClick = onItemClick;
  }

  onClick = (e) => {
    if (e.target.className === 'carrot') {
      e.target.remove();
      this.count--;
      this.onItemClick && this.onItemClick('carrot');
    } else if (e.target.className === 'bug') {
      this.onItemClick && this.onItemClick('bug');
    }
  };
}
profile
대체불가능한 사람이다

0개의 댓글

관련 채용 정보