당근 게임을 만들면서 아래의 코드를 실행했을 때 undefined
가 출력되었다.
this.field.addEventListener('click',this.onClick)
this.onClick은 할당이 되어있는 상태였는데 왜..?
이유는 click의 콜백으로 전달할 때 클래스의 정보는 안 넘어가기 때문이었다.
그래서 this를 공부하고 정리했다.
this는 함수가 호출될 때 결정된다.
전역공간에서 this는 전역 객체를 가리킨다
함수 호출시 : 전역객체
함수를 호출하는 순간 함수를 실행하는 주체는 전역객체이기 때문
function a(){ console.log(this); //window } a()
function b(){
function c(){
console.log(this)
}
c()
}
b();// window
### 메서드 호출시 : 호출한 대상 객체가 바인딩 됨
``` javascript
var d = {
e:function(){
function f(){
console.log(this);
}
f(); // window
}
}
d.e() // d
callback 호출시 기본적으로는 함수내부에서와 동일하다.
- 기본적으로 함수의 this과 같다.
- 제어권을 가진 함수가 콜백의 this를 지정해둔 경우도 있다.(call, apply,bind)
call,apply,bind
function a(x,y,z){
console.log(this,x,y,z);
}
var b = {
bb:'bbb'
};
a.call(b,1,2,3) // {bb:"bbb"} 1 2 3
a.apply(b,[1,2,3]); // // {bb:"bbb"} 1 2 3
var c= a.bind(b);
c(1,2,3); // {bb:"bbb"} 1 2 3
var d = a.bind(b,1,2);
d(3) //{bb:"bbb"} 1 2 3
생성자함수 호출시
function Person(n,a){
this.name = n;
this.age = a;
}
var gisele1 = Person('나다',30);
console.log(window.name, window.age); // 나다, 30
var gisele2 = new Person('나다',30);
console.log(gisele); //Person{age:30,name:'나다'}
ES6의 Arrow function은 this를 바인딩하지 않고, 스코프 체인상의 this에 바로 접근할 수 있다.
다시 맨 처음 문제로 돌아와서 콜백 함수에 class를 바인딩하기 위해서는 세 가지 방법이 있다.
// 1. bind 함수로 this바인딩 해주기
this.onClick = this.onClick.bind(this);
// 2. 콜백함수 내부에서 화살표 함수로 event 넘겨주기
this.field.addEventListener('click', (event) => this.onClick(event));
// 3. onClick 함수를 화살표 함수로 선언하기
this.field.addEventListener('click', this.onClick);
...
onClick = (event) => {
// arrow function은 자동으로 this바인딩
const target = event.target;
if (target.matches('.carrot')) {
target.remove();
playCarrot();
this.onItemClick && this.onItemClick('carrot');
} else if (target.matches('.bug')) {
this.onItemClick && this.onItemClick('bug');
playBug();
}
};
'Javascript' 카테고리의 다른 글
파일 업로드 / 다운로드 (0) | 2021.11.30 |
---|---|
실행 컨텍스트 (0) | 2021.11.28 |
자바스크립트 런타임환경 (0) | 2021.09.11 |
이벤트 (0) | 2021.08.28 |
CRP(Critical render path, 브라우저 렌더링 순서) (0) | 2021.08.21 |