실행컨텍스트

hatban·2023년 3월 27일
0

실행 컨텍스트란?

자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적인 개념

  • 코드들이 실행되기 위한 환경이면서, 박스이자 컨테이너
  • 예를 들면, 함수 실행시 함수 실행에 해당하는 실행 컨텍스트(환경)가 생성되고, 자바스크립트 엔진에 있는 콜 스택에 쌓여 가장 위에 있는 컨텍스트와 관련된 코드들을 실행하면서(LIFO) 전체 코드의 순서를 보장한다.

실행컨텍스트의 Type

  1. 전역 실행 컨텍스트
  • 전역 영역에 존재하는 코드
  • 프로그램에 단 한 개만 존재하고, 함수 밖에 있는 코드는 전역 실행 컨텍스트에 있다.
  • 브라우저의 경우 window 객체, node.js의 경우 global 객체가 전역 실행 컨텍스트다

  1. 함수 실행 컨텍스트
  • 함수 내에 존재하는 코드
  • 각 함수는 고유의 실행 컨텍스트를 가지며, 함수가 실행되거나 호출 될 때에만 생성된다.

  1. eval() 실행 컨텍스트
  • eval 함수로 실행되는 코드
  • 이제는 쓰지 않는 eval함수에 의해 실행되는 실행 컨텍스트

Execution Stack

  • 주로 다른 프로그래밍 언어에서는 Call Stack이라고 불리며, LIFO 구조이다.
  1. 자바스크립트 엔진은 script요소를 처음 만나는 시점에서 전역 실행 컨텍스트를 생성하고 Stack에 push한다
  2. 엔진이 함수 호출을 찾으면 해당 함수에 대한 함수 실행 컨텍스트를 생성해 Stack의 맨 위로 푸시한다.
  3. 엔진은 실행 컨텍스트가 Stack의 가장 맨 위 함수를 실행한 뒤 함수 종료시 Stack에서 제거하고 이를 반복한다.

실행 컨텍스트 생성 로직

실행 컨텍스트는 Creation PhaseExecution Phase의 두 단계로 생성된다

1. 생성단계

생성 단계에서는 두 가지 일이 일어난다
1. Lexical Environment 구성 요소 생성
2. Variable Environment 구성 요소 생성

ExecutionContext ={
	LexicalEnvironment = <ref. to LexicalEnvironment in memory>,
	VariableEnvironment = <ref. to VariableEnvironment in memory>,
}

1.1 Lexical Environment

- 변수와 해당 변수에 대입된 값이 매핑되는 곳 
1. Environment Records
	- 함수와 변수 선언을 저장하는 곳
2. Reference to the outer environment
	- 현재 Lexical Environment에서 변수를 찾지 못하면 외부 환겨에서 해당 변수를 찾아 볼 수 있다
3. This binding
	- 전역 실행 컨텍스트에서 this는 전역객체
    - 함수 실행 컨텍스트에서 this는 함수가 객체 잠조에 의해 호출되면 해당 객체가 this, 아니라면 전역객체(window)를 가리킨다.

1.2 Variable Environment

- Variable Environment에서는 변수 var만 저장하고  Lexical Environment에서는 변수 let과 const바인딩을 가진다

2. 실행 단계

  • 모든 변수에 대한 값 할당이 완료되고 최종적으로 코드들이 실행된다

예제

let a = 20;
const b = 30;
var c;

function multiply(e, f) {
 var g = 20;
 return e * f * g;
}

c = multiply(20, 30);
  1. 생성단계(전역 변수 생성, 할당은 x)
    GlobalExectionContext = {
      LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // Identifier bindings go here
          a: < uninitialized >,
          b: < uninitialized >,
          multiply: < func >
        }
        outer: <null>,
        ThisBinding: <Global Object>
      },
      VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // Identifier bindings go here
          c: undefined,
        }
        outer: <null>,
        ThisBinding: <Global Object>
      }
    }
  2. 실행단계(전역변수 할당)
      GlobalExectionContext = {
    LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // Identifier bindings go here
          a: 20,
          b: 30,
          multiply: < func >
        }
        outer: <null>,
        ThisBinding: <Global Object>
      },
    VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Object",
          // Identifier bindings go here
          c: undefined,
        }
        outer: <null>,
        ThisBinding: <Global Object>
      }
    }
  3. 함수 muliply(20,30) 호출 => 생성단계
    FunctionExectionContext = {
    LexicalEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          // Identifier bindings go here
          Arguments: {0: 20, 1: 30, length: 2},
        },
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>,
      },
    VariableEnvironment: {
        EnvironmentRecord: {
          Type: "Declarative",
          // Identifier bindings go here
          g: undefined
        },
        outer: <GlobalLexicalEnvironment>,
        ThisBinding: <Global Object or undefined>
      }
    }
  4. 실행단계(변수 할당 끝)
    FunctionExectionContext = {
    LexicalEnvironment: {
      EnvironmentRecord: {
        Type: "Declarative",
        // Identifier bindings go here
        Arguments: {0: 20, 1: 30, length: 2},
      },
      outer: <GlobalLexicalEnvironment>,
      ThisBinding: <Global Object or undefined>,
    },
    VariableEnvironment: {
      EnvironmentRecord: {
        Type: "Declarative",
        // Identifier bindings go here
        g: 20
      },
      outer: <GlobalLexicalEnvironment>,
      ThisBinding: <Global Object or undefined>
    }
    }
    
  5. 함수 완료 후 리턴값은 c 내부에 저장, 전역 렉시컬 환경 업데이트, 전역 코드 완료

호이스팅

  • 앞서 본 예시코드 처럼, 생성단계에서 변수 및 함수 선언을 스캔하고 선언이 저장되며, 처음엔 초기화 되지 않은 상태로 설정된다.
  • 이렇게 코드 실행 전 변수 선언이 먼저 메모리에 저장되어 선언 부분이 최상단으로 끌어올려지는 것처럼 보이는 것이 호이스팅이다.

후기

실행 컨텍스트의 경우 모던 자바스크립트 책을 통해서도 공부를 해봤고, 유튜브나 인터넷을 통해서도 가끔 다시 복습을 하는 개념이다. 그만큼 자바스크립트로 개발을 할 때 중요한 개념이란것을 알기 때문에.. 가끔 자바스크립트로 개발을 하다보면 예상치 못한 에러를 (자주)마주하게 되는데..보통 이런 자바스크립트의 동작 원리에 대한 이해도가 부족해서 그런 것 같다! 열심히 공부해야지

0개의 댓글