[JS] this와 실행 컨텍스트(Execution Context)

전상욱·2021년 5월 18일
2

JavaScript

목록 보기
8/17
post-thumbnail

this

인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어있다.
호출되는 시점과 상황에 따라 값이 달라져 디버깅을 유발하는 키워드이다.

consolethis를 찍었을 때 console에는 window객체가 출력된다.
일반적으로 브라우저의 요소와 자바스크립트 엔진과 관련된 모든 정보를 포함하고 있는 객체이다.

문법에 따라 this가 바뀐다.

Q. function() => { }(화살표 함수)의 차이점 ?
A. this가 서로 다르다.
B. functionthis를 가지고 있고, 화살표함수는 this를 가지지 않는다.

//서로 다른 값이 출력

function Fn() {
  console.log(this);
}
------------------------------
const arrowFn = () => {
  console.log(this);
}

직접 작성을 해보면 두 코드 전부 window객체를 출력한다.
그 전에 실행 컨텍스트의 개념을 알아야 한다.

실행 컨텍스트 (Execution Context)

실행 컨텍스트란?

  • 자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적인 개념
  • 코드가 실행된다면 실행 컨텍스트 내부에서 작동하고 있는 것

실행 컨텍스트 분류

  • Global Execution Context
    기본적으로 코드가 실행되는 영역이며 여기서 글로벌 객체인 window 객체를 생성하며, this를 글로벌 객체(window객체)로 설정한다.

  • Functional Execution Context
    각각의 함수가 가지는 실행 컨텍스트로, 함수가 호출될 때 해당 실행 컨텐스트가 생성된다.

언제 this가 바뀔까?

this는 기본적으로 window 객체를 말한다. (Node.js에서는 Global 객체)

하지만 this의 값이 바뀌는 경우가 생긴다.
this 값이 어떻게 바뀌고 있는지, 해당 this가 무슨 값인지 알기 위해서 코드의 문맥을 살펴볼 필요가 있다.

객체의 메소드를 호출하는 경우

const Obj = {
  value: 10,
  window: this,
  Fn: function() {
    console.log(this);
  },
  arrFn: () => {
    console.log(this);
  }
}

Obj.Fn();    // Obj객체
Obj.arrFn(); // window객체

MDN의 설명

  • 함수를 어떤 객체의 메소드로 호출하면 this의 값은 해당 객체를 사용한다.
  • ES2015에서는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.

이것이 아까 위에서 나왔던 답변의 정확한 의미이다.
function 키워드는 해당 객체를 바인딩하여 this의 값을 변경하는 것이고, () => { } 는 상위 객체의 this를 그대로 받아 사용하는 것이다.

생성자를 통해 객체를 생성하는 경우

function foo(name, age) {
  this.name = name;
  this.age = age;
}

// 생성자를 사용하지 않은 경우 - 단순 호출
const A = foo('SangUk', 24);
console.log(window.name, window.age);

// 생성자를 통한 객체 생성
const B = new foo('SangUk', 24);
console.log(B.name, B.age);

new 키워드를 통해 객체를 생성하면, this가 해당 객체에 바인딩 되어 해당 값을 읽게되는 것이다.
ES6에 추가된 class를 사용하면 동일하게 작동하는 것을 볼 수 있다.

예외적인 경우

jQuery 또는 React 등에 일부 라이브러리에서 엘리먼트에 이벤트를 추가할 때, 콜백함수에서 this를 사용하면 값이 바뀌는 경우가 존재한다.

// jQuery
$('div').on('click', function() {
  console.log(this);  // <div>객체
  function Fn() {
    console.log(this);  // window 객체
  }
  const arrFn = () => {
    console.log(this);  // <div> 객체
  }
});

위의 코드처럼 라이브러리 상에서 this를 바인딩 해주는 경우가 있기도 하니 this를 사용할 때는 해당 라이브러리의 document를 찾아보는 것도 중요하다.

profile
더 높은 곳으로

0개의 댓글