Javascript

Execution Context(실행 컨텍스트)

Jay-JI 2024. 7. 29. 19:45

Lexical Environment(어휘적 환경) 란

  • 코드가 어디서 실행되며 주변에 어떤 코드가 있는지 대체적인 정보를 담고 있는 환경
  • 함수 본인 내부의 식별자, 식별자에 바인딩 된 값 등을 기록하고 있는 하나의 자료구조
  • 이러한 Lexical Environment가 모여서 코드의 문맥을 구성한다.

 

Lexical Environment의 구성 요소

  • Environment Record (환경 레코드)
    - 변수와 함수 선언을 저장
    - ex) 함수 내부의 변수와 함수 선언이 저장

  • Outer Environment Reference (외부 환경 참조)
    - 상위 lexical environment 가리킴
    - 이를 통해 함수가 중첩되어 있을 때 내부 함수가 외부 함수의 변수와 함수에 접근 가능

 

Execution Context(실행 컨텍스트) 란

  • 자바스크립트에서 코드가 실행되는 환경을 의미한다.
  • 모든 코드는 실행 컨텍스트에서 평가되고 실행된다.
  • 자바스크립트 엔진은 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 객체를 구성하고, 이를 콜 스택에 쌓아 올렸다가, 가장 위에 쌓여 있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.

 

Execution Context의 구성 요소

  • Variable Environment
    현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보다. 선언 시점의 Lexical Environment의 스냅샷으로, 식별자의 변경 사항은 반영되지 않는다.

  • Lexical Environment
    처음에는 Variable Environment와 같지만 식별자의 변경 사항이 실시간으로 반영된다.

  • This Binding
    this 식별자가 바라봐야 할 대상 객체를 의미한다.

 

Execution Context 예시

 

다음과 같은 코드가 있다고 가정하자

const globalVar = 'global';

function outerFunction() {
    let outerVar = 'outer';
    
    function innerFunction() {
        let innerVar = 'inner';
        console.log(globalVar); // 'global'
        console.log(outerVar);  // 'outer'
        console.log(innerVar);  // 'inner'
    }
    
    innerFunction();
}

outerFunction();

 

위 코드에 대해서 각각의 Execution Context 정보는 다음과 같이 생성된다.

 

Execution Context (Global)
---------------------------
Variable Environment:
  globalVar: 'global'
  outerFunction: <function>

Lexical Environment:
  Environment Record(환경 레코드):
    globalVar: 'global'
    outerFunction: <function>
Outer Environment Reference(외부 환경 참조): null

this Binding:
  Global Object (e.g., window in browsers)

 

Execution Context (outerFunction)
---------------------------
Variable Environment:
  outerVar: 'outer'
  innerFunction: <function>

Lexical Environment:
  Environment Record(환경 레코드):
    outerVar: 'outer'
    innerFunction: <function>
  Outer Environment Reference(외부 환경 참조): Global Lexical Environment

this Binding:
  undefined (strict mode일 경우) 또는 Global Object (non-strict mode)

 

Execution Context (innerFunction)
---------------------------
Variable Environment:
  innerVar: 'inner'

Lexical Environment:
  Environment Record(환경 레코드):
    innerVar: 'inner'
  Outer Environment Reference(외부 환경 참조): Outer Function Lexical Environment

this Binding:
  undefined (strict mode일 경우) 또는 Global Object (non-strict mode)

 


 

Execution Context (실행 컨텍스트) 의 실행 단계

 

실행 컨텍스트는 다음과 같이 두 단계를 거쳐서 만들어진다.

 

  1. 생성 단계(Creation phase) - 변수의 '선언'을 읽는다
    - Lexical Environment 구성
      - Environment Record (환경 레코드) 생성
          - 현재 실행 컨텍스트 내에서 사용되는 변수, 함수 선언을 기록
          - var로 선언된 변수는 undefined로 초기화되고, let과 const로 선언된 변수는 초기화되지 않은 상태로 남는다.
          - 함수 선언(function) 전체가 메모리에 로드 됨
      - Outer Environment Reference (외부 환경 참조)
          - 현재 실행 컨텍스트가 참조하는 외부 Lexical Environment를 가리킨다.
    - Variable Environment 구성
    - this 바인딩 결정
      - 실행 컨텍스트가 생성될 때 this가 가리키는 객체를 결정
       - 전역 컨텍스트의 경우 this는 전역 객체를 가리킨다 (브라우저에서는 window 객체)

  2. 실행 단계(Execution phase) - 변수의 '값'을 읽는다.
    - 변수 값 할당
       - var로 선언된 변수에 실제 값이 할당된다.
       - let과 const로 선언된 변수는 TDZ(Temporal Dead Zone)에서 벗어난 후 값이 할당된다.
    - 코드 실행
      - 코드가 순차적으로 실행되며, 함수 호출 및 변수 할당이 이루어진다.
      - 각 변수와 함수는 해당 실행 컨텍스트의 Lexical Environment에서 값을 읽고 쓴다.

아래와 같은 코드가 있을 때 실행 컨텍스트는 다음과 같은 순서라 작동한다.

var temp = 'test';

function b (){
  console.log('hello world');
}

function a (){
  b();
}

a();

 

 

 

* 처음 자바스크립트 코드를 실행하는 순간 첫번째 그림처럼 Global Execution Context(전역 컨텍스트)가 콜 스택에 담긴다. 브라우저 환경에서 window 객체를 사용할 수 있는 이유가 이것 때문이다.

 

  1. 콜 스택엔 전역 컨텍스트를 제외하곤 다른 컨텍스트가 없기에 전역 컨텍스트와 관련된 코드를 진행한다.

  2. 전역 컨텍스트와 관련된 코드를 진행 중 a함수를 실행하였기에 a 함수의 환경 정보들을 수집하여 a 실행 컨텍스트를 생성, 콜 스택에 담는다.
    콜 스택 최상단에 a 실행 컨텍스트가 있기에 기존의 전역 컨텍스트와 관련된 코드의 실행을 일시적으로 중단한 후 a 실행 컨텍스트의 코드를 실행한다.

  3. a 함수 내부에서 b 함수를 실행하였기에 b 함수의 환경 정보들을 수집, 실행 컨텍스트를 생성, 콜 스택에 담는다.
    이전과 똑같이 콜 스택 최상단에 b 실행 컨텍스트가 있기에 기존 a 실행 컨텍스트와 관련된 코드의 실행을 일시적 중단한다.

  4. b 함수가 종료된 후 b 실행 컨텍스트가 콜 스택에서 제거된다.
    제거 후 콜 스택 최상단에는 a 실행 컨텍스트가 있기에 이전에 중단된 지점부터 코드 진행이 재개된다.

  5. a 함수 또한 종료된 후 실행 컨텍스트가 콜 스택에서 제거된다.
    이후엔 전역 공간에 실행할 코드가 남아있지 않다면 콜 스택에서 전역 컨텍스트 또한 제거되며 콜 스택에 아무것도 남지 않은 상태로 종료된다.

출처 : 
https://www.youtube.com/watch?v=EWfujNzSUmw&t=103s
https://www.youtube.com/watch?v=QkCNba92Vqo
https://gamguma.dev/post/2022/04/js_execution_context
https://techwell.wooritech.com/docs/languages/javascript/execution-context/
https://heycoding.tistory.com/86
https://meetup.nhncloud.com/posts/129
http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-2-lexical-environments-ecmascript-implementation/
https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts
https://velog.io/@paulkim/e
https://velog.io/@hamelln/execution-context