web study/JavaScript

[JavaScript] this와 Execution Context

0youn 2021. 7. 16. 15:22

javascript의 this는 신기한 친구다. 환경에 따라 가리키는 대상이 달라지기 때문인데

오늘은 this와 실행 컨텍스트에 대해 포스팅 하고자 한다.

this란

this는 일반적으로 메소드를 호출한 객체가 저장되어 있는 속성이다.

this는 함수를 호출하는 방법에 의해 결정되는데 이게 무슨말이냐면 실행하는 동안의 할당에 의해 설정될 수 없고

함수가 호출될 때 마다 다를 수 있다는 뜻이다.

this는 크게 4가지의 경우에서 각각 가리키는 객체가 다르게 설정된다.

  1. 기본 바인딩
  2. 암시적 바인딩
  3. 명시적 바인딩
  4. new 바인딩

기본 바인딩

 일반적으로 함수 내부에서 this를 사용할 경우 이 this는 javascirpt의 실행 환경의 전역 객체인 window를 가리킨다.

function testCode(){
 console.log(this) // window 객체를 가리킨다.
 this.a = "전역객체"
}
console.log(this.a) // undefined
testCode()
console.log(this.a) // 전역객체

전역 객체는 일반 객체처럼 아무 제약 없이 동작하기 때문에 this 사용에 주의해야 한다.

 

암시적 바인딩

 암시적 바인딩은 어떤 객체를 통해 함수가 호출된다면 그 객체가 this의 context 객체가 된다는 것이다.

function testCode() {
  console.log(this.a);
}

var obj = {
  a: 20,
  func1: testCode,
  func2: function() {
    console.log(this.a);
  }
};

obj.func1(); // 20
obj.func2(); // 20

 

명시적 바인딩

 함수에는 call, apply, bind 메소드가 있는데 첫 번째 인자로 넘겨주는 객체가 this가 된다

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

var obj = { name: "yuddomack" };
test.call(obj); // { name: 'yuddomack' }

 

new 바인딩

 자바스크립트에서 new를 사용하면 새로운 인스턴스가 생성되는데 생성된 인스턴스가 this가 된다.

function testCode(a) {
  this.a = a;
  this.b = 20;
}

var bar = new testCode(2);
console.log(bar.a); // 2
console.log(bar.b); // 20

 

실행 컨텍스트란(Execution Context)

실행 컨텍스트란 자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 개념이다. 즉 코드가 실행된다면 컨텍스트 내부에서 실행되고 있는 것이다. 쉽게 말하면 코드가 실행되고 있는 구역이라고 보는게 가장 직관적이라고 할 수 있을 것 같다.

 

자바스크립트 엔진은 코드를 실행하기 위해서 실행에 필요한 정보를 알고 있어야 한다.

크게 4가지로 구분되는데 변수, 함수 선언, 변수의 유효범위, this가 있다.

 

자 이제 this에 대해 알아보았는데 this는 실행 되는 환경에 따라 가리키는 객체가 달라지게 된다는 것을 알았다.

그러면 이 실행 환경이란 무엇인가에 대해 알아보도록 하자.

 

실행 컨텍스트의 종류

  1. 전역 컨텍스트(Global Context)
    • 함수 안에서 실행되는 코드가 아니라면 모두 전역 컨텍스트에서 실행된다.
    • 스텍 구조를 가지는 형태로 global object로 window가 this로 할당되고 스텍에 쌓이게 된다. 단 한개만 정의된다는 특징이 있다.
    • 이전 포스팅에서 진행한 call stack에 가장 먼저 추가되며 앱이 종료될 때 삭제 된다.
  2. 함수 컨텍스트(Functional Context)
    • 함수가 실행 될 때 마다 정의되는 컨텍스트 이다.
    • 함수 컨텍스트는 실행 시 마다 정의되며, 함수 실행이 종료되면 call stack에서 제거 된다.
    • closure를 사용한다면 스코프가 소멸하지 않는다는 특징을 가진다.
  3. eval 함수 컨텍스트
    • eval 함수도 자신만의 실행 컨텍스트를 가진다
    • 자바스크립트 개발자가 많이 사용하지 않는다는 특징을 가진다.

자바스크립트에서 호출 스택

 이전 포스팅에서는 자바스크립트 런타임 환경이 어떻게 함수들을 처리하는지에 대해 알아봤었다.

이제 실행 컨텍스트에 따른 비교를 해볼텐데 가장 먼저 전역 컨텍스트를 만들고 현재 실행되고 있는 호출 스텍에 이를 push 한다. 다른 함수가 호출되면 해당 함수에 대한 실행 컨텍스트를 생성하고 push하게 된다.

 

즉 전역 컨텍스트는 앱이 실행되고 나서 스텍에서 제거되지 않고 계속 유지되며, 함수 컨텍스트의 경우 실행이 완료(return)되면 컨텍스트에서 제거된다는 것을 알 수 있다.

 

실행 컨텍스트의 3가지 객체

  1. 변수 객체
    1. 실행 컨텍스트가 생성되면 정보들을 담을 객체를 엔진이 생성하게 된다.
  2. 스코프 체인
    1. 스코프 체인은 실행 컨텍스트가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 리스트를 가르킨다.
    2. 전역 객체와 함수 스코프의 레퍼런스를 저장한다.
    3. 자바 스크립트 엔진은 스코프 체인을 통해 렉시컬 스코프를 파악한다.
    4. 상위 함수, 전역 스코프 등을 참조할 수 있는 이유가 스코프 체인이 검색을 하기 때문이다.
  3. this
    1. this는 위에 설명했으므로 패스하겠다.

react에서 hooks가 등장하기 전까지는 클래스 컴포넌트를 주로 사용했기 때문에 this가 굉장히 중요했지만

요새는 this가 사용도 어렵고 직관적이지 않아서 잘 사용하지는 않는 추세라고 한다.

그래도 기본은 알고 있어야 하기에 오늘은 this와 실행 컨텍스트에 대해 정리해보았다.

아직 모르는 개념들이 있어 이해하기 어려웠지만 그래도 기본적인 원리에 대해 이해한거 같아 유익한 시간이 아닌가 생각이 들었다.

 

참고 자료

https://velog.io/@stampid/Execution-Context%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80

https://beomy.tistory.com/6

https://dkje.github.io/2020/08/30/ExecutionContext/