[ES6+] 클래스에서의 this


클래스를 사용해서 예문을 보도록 하자

//html
<span id="count">0</span>
<button id="plus">+</button>
<button id="minus">-</button>

//js
class Counter{
  constructor({initialNumber = 0,counterId, plusId, minusId}){
    this.count = initalNumber;
    this.counter = document.getElementById("counterId");
    this.plusBtn = document.getElementById("plusId");
    this.minusBtn = document.getElementById("minusId");
    
    this.addEventListeners();
  }
  addEventListeners(){
    this.plusBtn.addEventListener("click", this.increase);
    this.minusBtn.addEventListener("click", this.decrease);
  }
  increase(){
    this.count = this.count + 1;
    this.repainCount();
  }
  decrease(){
    this.count = this.count - 1 ;
    this.repainCount();
  }
  repaintCount(){
    this.counter.innerText = this.count;
  }
}

new Counter({
  counterId:"count",
  plustId:"plus",
  minusId:"minus"
});

위 코드로 +나 -를 클릭하면

repaintCount is not a function 이라면서 에러가 뜬다.

이유는 this 가 가리키는 대상이 변경되어서 이다.

클래스 외부에서 console.log(this) 를 하면

window 를 되돌려준다.

그리고 클래스 내부 메소드에서 this를 찍어보면 클래스를 가리킨다.

근데 addEventListener 로 메소드를 실행한후 그 안에 this 를 찍으면

엘리먼트를 가리킨다.

이게 자바스크립트의 기본 설정이다.

그래서 위의 코드에서 this.repainCount(); 를 찍으면 this가 엘리먼트를 가리키기 때문에 에러를 뿜는것이다.

그래서 만약 addEventListener를 사용함에도 불구하고 무조건 클래스를 가리키고 싶다면

화살표함수 를 사용해주면 된다



그럼 어떤 것이든 상관없이 무조건 클래스를 가리키게 된다

예시로 위의 increase 함수와 decrease 함수를 바꿔보자

increase = () =>{
  console.log(this);
  this.count = this.count + 1;
  this.repainCount();
}
decrease(){
  console.log(this);
  this.count = this.count - 1 ;
  this.repainCount();
}

increase는 화살표함수로 바꿔주었고 decrease는 냅두었더니

increase는 클래스를 가리키고

decrease는 element를 가리켜서 에러를 낸다


eventListener안에 handler를 넣으면 this는 event target을 가리키는 this로 변경된다

그러니 어떤 경우든 클래스로 가리켜 작동하게 하려면 화살표함수를 사용하길!






노마드코더의 ‘ES6의 정석’을 듣고 정리 =)




© 2018. by sora

Powered by sora