javascript

[자바스크립트] this 에 대해서 (call,apply,bind)

승딱 2021. 4. 13. 12:44
반응형

자바스크립트의 this는 함수가 호출되는 상황에 따라 동적으로 결정이 된다. ( >> this)

 

여기서 결정이 된다라는 것은 this 라는 객체에 어떠한 객체들이 와서 바인딩이 되는가 하는 사항이다.

 

반면 렉시컬 스코프는 함수가 선언될때 결정된다 (>> 클로저)


호출되는 상황에는 어떠한 것들이 있을까?

1.   함수호출

2.  생성자 함수 호출

3.  call / apply / bind

4.  메서드 호출


 

4. 메서드의 호출

 - 객체의 프로퍼티값이 함수라면 우리는 그것을 메서드라고 부른다. 

 - 메서드 내부의 this 는 메서드가 포함된 객체 를 가리킨다.

 

1.  일반적인 함수 호출 시에 함수내부의 this 는 전역 객체인 window (global)를 가리킨다.

왼쪽은 브라우저 콘솔에서 this를 찍었기 때문에 window 를 보여주고 오른쪽은 터미널에서 node 실행이후에 this 를 찍어본 모습으로 

global 객체를 보여준다.

함수를 선언하고 그안에서 봐도 동일한 window 객체가 this 에 바인딩 된것을 확인할수 있다.

 

2. 생성자 함수의 호출

- 보통호출이 아니라 생성자 역할을 하는 함수를 new 라는 키워드를 이용해서 호출하게 되는경우에는

   this 가 window 를 가리키는 것이 아니라 생성된 인스턴스를 가리킨다.

- 이때 new 키워드의 역할은 암묵적인(보이지않는) this 라는 빈 객체를 만들고 함수가 실행이 된다
- 그리고 이후에는 그 암묵적인 this 라는 객체를 반환 함으로써 생성자 역할을 하게 된다.

 

3.  위의 경우들은 자바스크립트 엔진이 내부적으로 this의 값을 정하는 원칙들이라면 call , apply , bind 는 코드 작성자가 this 의 값을

     명시 할수 있는 메서드 들이다.

 

- call 과 apply 는 this를 정해주고 바로 실행시키는 반면 bind 는 해당되는 함수의 this 값만 바인딩 해놓는 차이가 있다.

- call 과 apply 는 거의 똑같지만 두번째 인자로 함수의 매개변수가 들어오는 형태가 apply 는 배열형태로 들어오고 call 은 풀어서 들어오는것이 다른점이다.

 

예시를 확인해보자

함수의 일반적인 호출에서 this는 window 를 가리키는걸 확인할수있고 당연히 계산이 안된다

이번에는 명시적으로 this를 정해보자

첫번째 인자자리에 this가 될 객체를 넣어주고 이후에는 sample 함수의 매개변수 자리인데 call 의 경우 순차적으로 들어가지만 apply 는 배열형태로 들어가는것을 확인할수있다.

bind 의경우 함수가 호출되는것이아니라 함수자체가 반환되는것을 확인할수있다.

따라서 아래와 같이 사용할수있다.

 

인데요. 문제점은 this.onClickButton = this.onClickButton.bind(this); 를 하지 않으면 render 메소드에서 this.onClickButton 함수를 호출했을 때 함수의 this가 window undefined가 되어버립니다. 따라서 window나 undefined에는 setState 메소드가 없기 때문에 this.setState 호출 시 에러가 발생하죠.

콜백함수(setTimeout)