Core Javascript - this

김규빈·2021년 2월 17일
1
post-thumbnail
post-custom-banner

이 글은 Core Javascript를 읽고 내용을 정리하였습니다. 2회독 하였지만 잘못된 내용의 지적을 감사히 받겠습니다.

자바스크립트에서 가장 혼란스러운 개념의 this를 정리해야겠다.

this가 가장 혼란스러운 이유는 상황에 따라 바라보는 this의 대상이 달라지기 때문이라고 생각한다. 어떤 이유로 그렇게 되는지를 파악하기 힘든 경우도 있고 예상과 다르게 엉뚱한 대상을 바라보는 경우도 있기 때문에 this의 원리를 파악해서 컨트롤 할 수 있게 만드는게 목적이다.

상황에 따라 달라지는 this

자바스크립트에서 this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다. 실행 컨텍스트는 함수를 호출할 때 생성되므로, 바꿔 말하면 this는 함수를 호출할 때 결정된다. 즉 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라지는 것.

전역 공간의 this

전역 공간에서의 this는 전역 객체를 가르킨다. window다.

메서드로 호출시 내부의 this

this에는 호출한 주체에 대한 정보가 담긴다. 어떤 함수를 메서드로서 호출하는 경우 호출 주제는 바로 함수명 앞의 객체이다. 점 표기법의 경우 마지막 점 앞에 명시된 객체가 곧 this !

obj.methodA();			// methodA의 This는 obj

함수 vs 메서드

어떤 함수를 실행하는 방법을 여러 가지가 있는데, 가장 일반적인 방법 두 가지는 함수로서 호출하는 경우와 메서드로서 호출하는 경우이다. 프로그래밍 언어에서 함수와 메서드는 미리 정의한 동작을 수행하는 코드 뭉치로, 이 둘을 구분하는 유일한 차이는 독립성에 있다. 함수는 그 자체로 독립적인 기능을 수행하는 반면, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다. 자바스크립트는 상황별로 this 키워드에 다른 값을 부여하게 함으로써 이를 구현했다.

함수로서 호출시 내부의 this

어떤 함수를 함수로서 호출할 경우에는 this가 지정되지 않는다. this에는 호출한 주체에 대한 정보가 담긴다고 했는데 함수로서 호출하는 것은 호출 주체를 명시하지 않고 개발자가 코드에 직접 관여해서 실행한 것이디 때문에 호출 주체의 정보를 알 수 없는 것. 그렇기에 실행 컨텍스트의 스코프 체인에 의해 this는 전역객체 window가 된다.

이렇게 되면 우리가 생각하는 this의 단어가 주는 인상과는 다르게 됬다. 호출주제가 없을 경우엔 실행컨텍스트에서 변수가 스코프체인 되는 것 처럼 함수 호출 당시 주변 환경의 this를 그대로 상속받아 사용하고 싶다.

this를 우회하는 방법

1. self = this

var obj = {
  outer: function(){
    console.log(this);					// {outer: f}
    var innerFunc1 = function(){
      console.log(this);				// window{...}
    };
    innerFunc1();
    
    var self = this;
    var innerFunc2 = function(){
      console.log(self)					//{outer: f}
    }
    innerFunc2();
  }
};
obj.outer()
    

self 라는 변수에 this를 담아서 내부에서 self를 this처럼 사용하는 방법.
나는 스토어링크 기업협업 당시 이 방법을 통해 this를 우회해서 사용해 봤다. 그 당시에는 이해하지 못하고 CTO님이 알려주신 솔루션을 가져다 사용만 했었는데 지금 다시 생각을 해보면. 내부에서의 this는 window전역 객체를 가르키고 있기에 this.asd(변수)는 undefined이고, self라는 변수에 this를 내장시키고 내부 함수에서 self로 끌고와서 사용했다.

2. This 바인딩 하지 않는 함수 ! 화살표

var obj = {
  outer: function(){
    console.log(this);					// {outer: f}
    var innerFunc1 = ()=>{
      console.log(this);				// {outer: f}
    };
    innerFunc1();
    
  
};
obj.outer()

ES6 문법에서 새로 생겨난 화살표 함수! 아마 ES6 생겨난 기능중에 가장 많이 쓰이고 있을 것으로 생각됨.
화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 되어, 상위 스코프의 this를 그대로 활용할 수 있다.

콜백함수에서의 this?

함수 A를 함수 B에게 제어권을 넘겼을 경우 B의 this를 따르게 됨.

정리하자면 다음 규칙은 명시적 this 바인딩이 없는 한 늘 성립합니다.

- 전역공간에서의 this는 전역객체를 참조합니다.
- 어떤 함수를 메서드로서 호출한 경우 this는 메서드 호출 주체를 참조합니다.
- 어떤 함수를 함수로서 호출한 경우 this는 전역객체를 참조합니다. 메서드의 내부함수에서도 같습니다.
- 콜백 함수 내부에서의 this는 해당 콜백 함수의 제어권을 넘겨받은 함수가 정의한 바에 따르며, 정의하지 않은 경우에는 전역객체를 참조합니다.
- 생성자 함수에서의 this는 생성될 인스턴스를 참조합니다.

명시적으로 this를 바인딩 한 경우

- call, apply 메서드는 this를 명시적으로 지정하면서 함수 또는 메서드를 호출합니다.
- bind 메서드는 this 및 함수에 넘길 인수를 일부 지정해서 새로운 함수를 만듭니다.
- 요소를 순회하면서 콜백 함수를 반복 호출하는 내용의 일부 메서드는 별도의 인자로 this를 받기도 합니다.
profile
FrontEnd Developer
post-custom-banner

0개의 댓글