CoreJavaScript Chapter 3. [this]

JUGNMIN LEE·2021년 5월 1일
0

CoreJavaScript

목록 보기
3/7
post-thumbnail

일단 this는 자바스크립트의 개념중에서 무엇이 가장 헷갈리냐라고 했을때에 가장 많이 나오는 것이다.

여러 예시들을 확인하면서 비교해봤지만 최대한 이해한 부분을 간단하게 정리를 한 뒤
명시적으로 바인딩을 하는 방법과 예시들에 대해서는 따로 공부하고 해당 블로깅 글에는 생략한 채
필요할 때에 확인하여 사용하려고 한다.

CoreJavaScript

1. this란 ?

this가 결정이 될 때에는 아래와 같은 두가지 방법이 있다.
첫번째는 선언할때에 결정이 되는 경우가 있고 두번째는 호출할 때에 결정이 되는 경우가 있다
먼저 선언할때에는 클로저라는 개념과 연관 있으므로 나중에 설명하고 호출할 때에 주목해보자.

먼저 MDN을 살펴보면 this는 이렇게 정의 되어 있다.
대부분의 경우, this의 값은 함수를 호출하는 방법에 의해 결정된다.
실행하는 동안의 할당에 의해 설정될수 없고, 함수가 호출될 때 마다 다를 수 있다.
(여기서 호출될때 신경을 쓰지 않고 this를 묶어버릴 수 있는 방법이 ES5 함수에서는 bind라는 메소드가 있다)

var someone = {
  name : 'codemin',
  whoAmI : function(){
    console.log(this);
  }
}

someone.whoAmI(); //결과값 : { name: 'codemin', whoAmI: ƒ whoAmI() }

위의 코드를 보자
결과값은 자기 자신이다, 당연한 결과이다
this는 호출하는 방법에 의해 결정이 된다 someone.whoAmI() 라는건 결국 someone이 결정하였기 때문에 someone 자신이 나오게 된다.

그렇다면 방법을 달리 해보자.

var someone = {
  name : 'codemin',
  whoAmI : function(){
    console.log(this);
  }
}

var myWhoAmI = someone.whoAmI;
myWhoAmI(); //결과값 : window객체

위의 코드를 확인해보면 someone이 whoAmI를 someone.whoAmI로 실행했지만 결국 myWhoAmI에 담겨 호출이 되었기 때문에 전역에 있는 myWhoAmI는 window객체를 뿜어낸다.

그렇다 this는 간단하게 "호출하는 놈"에 따라 결정이 되기에 이렇게 다른 결과를 보여주게 된다.

그렇다면 이 코드는 어떨까 ?

var someone = {
  name : 'codemin',
  whoAmI : function(){
    console.log(this);
  }
}

var myWhoAmI = someone.whoAmI;
myWhoAmI(); //결과값 : window객체

var bindedWhoAmI = myWhoAmI.bind(someone);
bindedWhoAmI(); //결과값 : { name: 'codemin', whoAmI: ƒ whoAmI() }

아까 처음에 설명했듯이 호출될때를 신경쓰지 않고 "난 this는 이녀석으로만 하겠어!" 라고 고정을 시켜놓는 것이 bind다.
결국 myWhoAmI()와 bindedWhoAmI()는 실행되는 곳은 전역으로 window가 나와야 겠지만
bind로 someone 자체를 this로 고정시켜버렸기 때문에 결과 값이 다를 수 있는 것이다.

bind와 같이 이러한 행위를 명시적으로 this를 바인딩 했다고 하며 bind라는 메소드 말고도
call과 apply같은 메소드나 생성자 내부에서 다른 생성자를 호출을 하는 등 여러 방법이 있다.

혹은 요소를 순회하면서 콜백 함수를 반복적으로 호출하는 내용의 일부 메서드의 경우 별도의 인자로 this를 받기도 한다.

2. this를 우회하기

그렇다면 bind라는 메소드말고 부모 함수에서 안에 있는 내부 함수에게 this를 상속시켜서 호출 주체가 없을 때는 자동으로 전역객체를 바인딩하는 부분을 우회할 수는 없을까 ?

그 부분이 바로 ES6에서 화살표 함수가 그 기능을 해준다.

아래의 코드를 보자.

var obj = {
  outer : function () {
    console.log(this); //(1)결과값 : { outer: ƒ outer() }
    var innerFunc = () => {
      console.log(this); //(2)결과값 : { outer: ƒ outer() }
    };
    innerFunc();
  }
}

obj.outer();

원래 같으면 (1)의 결과는 this가 obj를 가르키는 것으로써 지금 결과 값과 동일 하겠지만
(2)의 경우에는 함수자체가 실행이 되어 실행되는 주체가 없기 때문에 window객체가 this로 가르켜졌어야 했다 하지만 화살표 함수를 이용해 실행 컨텍스트를 실행할 때에 this 바인딩 자체가 빠지게 되어 상위 스코프의 this를 그대로 활용 할 수 있게 된다.

3. this를 예측하기

this를 예측할때는 첫번째에서 설명했듯이 명시적 this 바인딩이 됬냐 아니면 없냐로 나뉘어 생각해봐야한다 그래야만 정확한 this 예측이 가능하다.

아래의 내용으로 정리가 된다.

명시적 this 바인딩이 없는 상태에서의 this 예측
1) 전역공간에서의 this는 전역객체를 참조한다.
2) 어떤 함수를 메서드로써 호출한 경우 this는 메서드 호출 주체(메서드명 앞의 객체)를 참조한다.
3) 어떤 함수를 함수로써 호출한 경우 this는 전역객체를 참조한다. 메서드 내부 함수에서도 동일하다.
4) 콜백 함수 내부에서의 this는 해당 콜백 함수의 제어권을 넘겨받은 함수가 정의한 바에 따르며, 정의하지 않은 경우에는 전역객체를 참조한다.
5) 생성자 함수에서의 this는 생성될 인스턴스를 참조한다.

명시적 this 바인딩을 한 경우 this 예측
1) call, apply 메서드는 this를 명시적으로 지정하면서 함수 또는 메서드를 호출한다.
2) bind 메서드는 this 및 함수에 넘길 인수를 일부 지정해서 새로운 함수를 만든다.
3) 요소를 순회하면서 콜백 함수를 반복 호출하는 내용의 일부 메서드는 별도의 인자로 this를 받기도 한다.


- - -

출처
모든 내용은 코어자바스크립트 공부를 하며 책 내용을 발췌해 이해한 내용들만 추려 적은 내용입니다 해당 코드들은 책 내용의 코드의 값들을 변경하거나 이해를 위해 그대로 가지고 왔습니다.

profile
Frontend Developer

0개의 댓글