this
는 this
를 사용한 함수가 어떻게 불리느냐(어디에서 호출되느냐)에 따라 가리키는 값이 달라진다.
따라서 원하는 this를 지정해주기 위한 method가 있는데
바로 call
, apply
, bind
이다.
이중 call
과 apply
는 this를 지정해줌과 동시에 함수를 호출하며bind
는 호출하지 않는다는 차이점이 있다.
오늘은 bind
를 사용하여 비동기함수인 setTimeout
의 this를 제어해 보자.
왜 setTimeout의 this는 요상할까??
setTimeout의 this는 조금은 의도와는 다르게 작동한다.strict모드
일 때는 undefined가 호출되고,strict모드
가 아닐 때는, 전역객체 (window 혹은 global)가 호출된다.
왜일까??
이건 이벤트루프,스택,큐와 관련된 내용인데
앞서 말했듯이 setTimeout함수는 비동기함수이다.
따라서 setTimeout함수의 대상이되는 this는 콜스택에 들어갔다가, setTimeout함수를 web ApIs에 전달하고
콜스택에서 pop()된다.(👈)
이후, setTimeout에서 설정한 시간이 지나면, setTimeout의 매개변수로 들어간 실행함수가
태스크큐로 들어가고, 콜스택이 비면 이벤트루프에의해 콜스택으로 들어가 실행된다.
이때 즉, setTimeout의 실행함수가 실행될 때, 실행함수의 this는 ???
위의 (👈)에서 이미 pop()되어 사라졌다.
따라서 this값이 의도와다르게 설정되는 것이다.
bind로 setTimeout의 this 제어하기
setTimeout에 bind메소드를 사용할 떄는,
setTimeout의 실행함수에 사용해야한다!
//나의 실수
step() {
setTimeout.bind(this, this.step, this.timeBetweenSteps);
}
//올바른 사용
step() {
setTimeout(this.step.bind(this), this.timeBetweenSteps);
}
setTimeout 안에 익명함수를 넣을때는,
그냥 arrow function
을 사용하면 된다.
'개인공부 > TIL(Today I Learned)' 카테고리의 다른 글
TIL 46일차_알고리즘문제_잘린 사각형의 개수 (0) | 2021.03.05 |
---|---|
TIL 45일차_알고리즘_이진탐색트리 (0) | 2021.03.04 |
TIL 43일차_1급시민 (0) | 2021.03.02 |
TIL 42일차_상속 방법 두가지: pseudoClassical패턴과 ES6+ class문법 (0) | 2021.03.01 |
TIL 41일차_상속과 프로토타입 (0) | 2021.02.28 |