This

Gisele·2021년 11월 28일
0

Javascript

목록 보기
12/14
post-thumbnail

당근 게임을 만들면서 아래의 코드를 실행했을 때 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  

메서드 호출시 : 호출한 대상 객체가 바인딩 됨

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();
    }
  };
profile
한약은 거들뿐

0개의 댓글