This와 Binding

movie·2022년 3월 3일
5
post-thumbnail

This와 Binding 😛

들어가기 전..

this란?

  • 현재 실행되는 실행 컨텍스트를 가르킨다.
  • 자바스크립트에서의 this함수를 호출하는 방법에 의해 결정된다.

실행 컨텍스트 (Execution Context)란?

  • 실행 가능한 코드가 실행되기 위해 필요한 환경

    • 실행 가능한 코드
      • 전역 코드 : 전역 영역에 존재하는 코드
      • eval 코드
      • 함수 코드 : 함수 내에 존재하는 코드
  • 자바스크립트 엔진에 의해 실행됨


자바스크립트 엔진이란?

자바스크립트 코드를 실행하는 인터프리터 - JS 엔진


window 객체란?

  • 브라우저 요소, 자바스크립트 엔진, 모든 변수를 가지고 있는 객체


들어가기 직전..🧐

...

function first() {
  ...

  function second() {
    ...
  }

  second();
}

first();

위 코드를 실행하면 어떻게 될까?

실행 컨텍스트는 스택구조로 생성, 소멸되는데 실행 중인 컨텍스트에서 이 컨텍스트와 관련없는 코드(예를 들어 다른 함수)가 실행되면 새로운 컨텍스트가 생성된다. - 실행 컨텍스트


  • 실행 컨텍스트 스택
second EC *
first EC *first ECfirst EC *
global EC *global ECglobal ECglobal ECglobal EC *
  1. 전역코드로 컨트롤이 진입하면서 global EC가 생성되고 실행 컨텍스트 스택에 쌓인다. (global EC는 브라우저가 닫힐 때까지 유지)
  2. 함수가 호출되면 해당 함수의 EC가 생성되고, 직전 실행 컨텍스트 위에 쌓인다.
  3. 함수의 실행이 종료되면 해당 함수의 EC가 소멸되고, 컨트롤을 직전 코드 컨텍스트에게 반환한다.


this는 어떻게 변경될까?

this함수를 호출하는 방법에 의해 결정된다.

함수를 호출하는 방법this
일반 함수 호출시전역 객체 (window 객체)
메서드 호출시메서드를 호출한 객체
생성자 함수 호출시생성자로 만들어낸 객체
call, apply, bind인자로 전달된 객체

기본

  • 기본적으로 this전역 객체를 가르킨다. (브라우저에서 전역 객체는 window 객체)

내부 함수 호출시

function executeFunction() {
  function printThis() {
    console.log(this);
  }

  printThis();
}

executeFunction(); // window 객체
  • 일반 함수 내부에서 this를 출력하는 함수를 호출하면 this는 window 객체를 가르킨다.

일반 함수 호출시 = 단순 호출

function printThis() {
  console.log(this);
}

printThis(); // window 객체
  • 일반 함수를 크게 보면 전역 객체 (window 객체)의 메서드로 볼 수 있다. window 객체의 메서드이므로 this가 window 객체를 가르킨다고 보면 된다.

객체의 메서드 내부

const obj = {
  printThis() {
    console.log(this); // obj 객체
  },
};

obj.printThis();
  • 객체의 메서드 내부에서 this를 출력하는 함수를 호출하면 this는 obj 객체를 가르킨다.

일반 함수 방식 VS 메서드 방식

const obj = {
  printThis() {
    console.log(this);
  },
};

let printThis = obj.printThis;

printThis(); // window 객체 - 일반 함수 방식
obj.printThis(); // obj 객체 - 메서드 방식

생성자 함수 내부

var globalValue = 'globalValue';

function printThis() {
  this.objectValue = 'objectValue';

  console.log(this.globalValue, this.objectValue);
}

printThis(); // globalValue objectValue [this = window 객체]
var obj = new printThis(); // undefined "objectValue" [this = obj 객체]
  • new키워드를 통해 생성자 함수를 실행하면, this가 생성자를 통해 생성되는 객체를 가르킨다.
    • 객체 안에 glovalValue가 존재하지 않으므로 undefined가 출력된다.
  • printThis를 생성자 함수가 아닌 일반 함수로 실행하면 this는 window 객체를 가르킨다.
    • window 객체 안에는 모든 변수가 존재하므로 globalValue, objectValue 둘다 정상적으로 출력된다.

Event Listener 호출시 this를 출력하면?

$('#button').addEventListener('click', function () {
  console.log(this); // button 객체
});
  • 객체의 메서드 내부에서 실행하는 것과 같다.


..그래서 바인딩🔗이 뭔데

바인딩이란?

  • this가 특정 객체에 연결되는 것이다.
  • call, apply, bind함수로 this를 변경할 수 있다.

EX | bind

  • bind()의 인자로 전달된 객체를 새로 생성되는 함수안에서의 this가 가르키도록 함.
  • 새로운 함수를 생성하는 방식
function originalFunction(a, b) {
  console.log(this.objValue); // objValue
  // bind()를 통해 this가 obj를 가르키게 됨

  console.log(a, b); // 1, 2
}

const obj = {
  objValue: 'objValue',
};

const boundedFunction = originalFunction.bind(obj);
// bind()를 통해 boundedFunction안의 this가 obj를 가르키게 됨

boundedFunction(1, 2); // a와 b전달


화살표함수는 this가 정적으로 결정된다고?!

화살표함수는 call, apply, bind함수로 this를 변경할 수 없다. 왜냐면 정적으로 this가 가르키는 객체가 결정되기 때문!

  • 화살표 함수 내부의 this는 언제나 상위 스코프의 객체를 가르킨다.
    • 이를 Lexical this (문맥적 this)라고 한다.

그런데 화살표 함수를 사용하면 안되는 경우가 있다.

  • 메서드를 정의하는 것 (this가 window 객체를 가르킴)
  • addEventListener의 콜백함수 (this가 window 객체를 가르킴)



참고

profile
영화보관소는 영화관 😎

0개의 댓글