[자바스크립트 궁금한 점] 함수표현식의 this바인딩

addEventListner

addEventListener함수는 콜백함수의 this를 event타겟으로 바인딩한다.

arrow function : 함수표현식

콘솔에 TodoInput 클래스가 찍힌다.

TodoInput {$todoInput: input#new-todo-title.new-todo, onKeyUpListener: ƒ, onKeyUp: ƒ}

addEventListener 함수의 this 바인딩에 영향을 받지 않았다.

함수선언식

콘솔에 $todoInput 요소(element)가 찍힌다.

<input id="new-todo-title" class="new-todo" placeholder="할일을 추가해주세요" autofocus>

addEventListener 함수에 의해 this가 event타겟으로 바인딩 되었다.

왜 이런 차이가 발생할까?

주어진 정보

함수 선언식으로 작성하면 함수의 this는 addEventListener의 this 바인딩에 영향을 미친다.

함수 표현식으로 작성하면 함수의 this는 addEventListener의 this 바인딩에 영향에 미치지 않고 본래(?)의 this를 유지한다.

내가 내린 결론

export class Field {
  constructor(carrotCount, bugCount) {
    ...
    this.$field.addEventListener('click', this.onClick);
  }
  
  // 함수 선언식  
  onClick(event) {
      this.onItemClick(ItemType.carrot);
  };
    
  // 함수 표현식  
  onClick = event => {
      this.onItemClick(ItemType.carrot);
  };
}
  1. 함수 실행시에는 전역(window) 객체를 가리킨다.
  2. 메소드 실행시에는 메소드를 소유하고 있는 객체를 가리킨다.
  3. 생성자 실행시에는 새롭게 만들어진 객체를 가리킨다.

클래스 안에 서 정의된 this는 객체로 this바인딩이 되어진다. 그래서 this.메서드 혹은 this.프로퍼티 이렇게 정의를 하면 객체.메서드, 객체.프로퍼티 라고 사용하게 된다.

하지만 addEventListener 메서드는 콜백함수의 this를 자동으로 이벤트가 발생한 타겟으로 this바인딩을 하도록 정의되어있다.

따라서 위에 onclick 함수에서 this가 해당 클래스의 정보가 전달되지 않고 이벤트타겟이 전달되기 때문에 오류가 발생한다.

따라서 this바인딩을 통해서 this에 해당 클래스로 정의를 해야한다.

this바인딩

  1. bind() 메서드
this.onClick = this.onClick.bind(this)
  1. 화살표함수

일반 함수는 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다

화살표 함수의 this 언제나 상위 스코프의 this를 가리킨다.

this.$field.addEventListener('click', (event) => this.onClick(event));

// 또는

onClick = event => {
      this.onItemClick(ItemType.carrot);
  };

좋은 웹페이지 즐겨찾기