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

+ Recent posts