[JavaScript] 실행 컨텍스트

수민🐣·2022년 12월 22일
0

JavaScript

목록 보기
31/32

실행 컨텍스트(Execution Context)

자바스크립트 엔진이 코드를 실행하기 위해서는 코드에 대한 정보들이 필요하다.
코드에 선언된 변수와 함수, 스코프, this, arguments 등을 묶어, 코드가 실행되는 위치를 설명한다는 뜻의 Execution Context라고 부른다.
자바스크립트 엔진은 Execution Context를 객체로 관리하며 코드를 Execution Context내에서 실행한다.

Execution Context의 종류

1. Global Execution Context

코드를 실행하며 단 한 개만 정의되는 전역 Context
global object를 생성하며 this 값에 global object를 참조한다.
전역 실행 컨텍스트는 Call Stack에 가장 먼저 추가되며 앱이 종료 될 때 삭제된다.

2. Functional Execution Context

함수가 실행 될 때마다 정의되는 Context
매 실행시마다 정의되며 함수 실행이 종료(return)되면 Call Stack에서 제거된다.

3. Eval Context

eval 함수로 실행한 코드의 Context
보안상 취약한 점이 있어 비권장 함수이다.

Execution Context의 관리 : CallStack

js엔진은 생성된 Context를 관리하는 목적의 Call Stack을 갖고 있다.
js는 단일 스레드 형식이기 때문에 런타임에 단 하나의 Call Stack이 존재한다.
Call Stack은 최대 stack 사이즈가 정해져 있다. Call Stack에 쌓인 Context Stack이 최대치를 넘게 될 경우 'RangeError: Maximum call stack size exceeded’라는 에러 발생 = Stack Overflow

  1. 전역 범위의 코드를 실행하며 Global Execution Context를 생성해 stack에 push
  2. 함수가 실행 또는 종료 될 때마다 Global Execution Context의 위로 Functional Execution Context의 stack를 push 또는 pop

  1. 코드의 전역 범위가 실행되며 Global Execution Context를 push합니다.
  2. fn1이 실행됩니다.
  3. fn1의 Functional Execution Context가 Call Stack에 push됩니다.
  4. fn2이 실행됩니다.
  5. fn2의 Functional Execution Context가 Call Stack에 push됩니다.
  6. console.log가 실행됩니다.
  7. console.log의 Functional Execution Context가 Call Stack에 push 됩니다.
  8. console.log의 실행이 완료되며 console.log의 Functional Execution Context가 pop됩니다.
  9. fn2의 실행이 완료되며 fn2의 Functional Execution Context가 pop됩니다.
  10. fn1의 실행이 완료되며 fn1의 Functional Execution Context가 pop됩니다.
  11. 앱 종료 시 Global Execution Context가 pop됩니다.

Execution Context의 구성

LexicalEnvironmentVariableEnvironment의 두 가지 구성으로 이루어지며, Environment들은 생성 시 같은 속성 카테고리를 가지고 있다.

ExecutionContext :{
    LexicalEnvironment:{
        Environment Records,
        Reference to the outer environment,
    },
    VariableEnvironment:{
        Environment Records,
        Reference to the outer environment,
    }
}

공통 속성 : Reference to the outer environment

외부 환경 참조는 정적 스코프를 기준으로 상위 scope의 Lexical Environment를 참조한다.

즉, 가장 먼저 생성 되는 Global Execution Context는 외부 환경 참조 값으로 null를 갖는다. 그리고 Functional Execution Context는 상위 Scope에 해당하는 Lexical Environment를 외부 환경 참조 값으로 갖는다. 이 연결 고리는 변수 탐색 시 사용된다.

scope chain = Lexical nesting structure

일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례대로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결되고 있는지 보여주는 것
즉, 자기 자신의 스코프를 제외한 자신과 가장 가까운 변수 객체의 모든 스코프들

let name = "Jason";
function fn1() {
    console.log(name); //Jason
}
function fn2() {
    let name = "Peter";
    console.log(name); // Peter
    fn1();
}
fn2();
  1. fn1() 내부의 console.log는 name 변수 탐색 시 가장 먼저 자신의 Lexical Environment를 확인
  2. 찾지 못했을 경우, 자신의 외부 환경 참조인 Global Lexical Environment에서 변수 탐색

공통 속성 : Environment Record

Lexical Environment 내에 식별자 바인딩을 기록하는 객체이며 Environment Record를 상속하는 세개의 서브 클래스로 구성되어 있다.

Environment Record:{
   Declarative Environment Record,
   Object Environment Record,
   Global Environment Record
}

Declarative Environment Record
함수와 변수, this, super 등의 식별자 바인딩이 저장 되며, Variable Environment와 Lexical Environment는 각각 다른 방식으로 선언된 변수들을 관리한다.

  • Variable Environment에는
    • var로 선언된 변수가 메모리에 매핑되며 초기값으로 undefined가 할당 된다. 변수 값 할당 코드가 실행되기 전 변수에 접근하게 되면 undefined 값을 얻게 된다. 할당 코드가 실행되고 난 뒤에는 해당 값으로 수정 된다.
    • 선언형 함수가 메모리에 매핑되면 함수 전체가 메모리에 할당된다.
  • Lexical Environment에는
    • let, const로 선언된 변수 : 변수가 메모리에 매핑되지만 초기값이 할당되지 않는다.
      변수 값 할당 코드가 실행되기 전 변수에 접근하게 되면 reference error가 발생
      변수 값 할당 코드가 실행되고 난 뒤 메모리에 값이 추가 된다.

Lexical Environment vs Variable Environment?

Variable Environment는 Lexical Environment를 상속하는 관계
그래서 Lexical Environment와 Variable Environment 모두 Lexical Environment라고 말할 수 있다.

Lexical Environment는 let과 const로 선언된 변수들을 위한 local lexical scope를 단위로 한다.
Variable Environment는 var로 선언된 변수들을 위한 functional scope를 단위로 한다.

Context의 생성 과정

Execution Context는 Creation과 Execution의 두 단계를 거쳐 생성된다.

1. Creation Phase
Creation 단계에선 Lexical EnvironmentVariable Environment의 정의가 이루어진다.
This bindingOuter Reference를 결정하고, Environment Record에 변수 식별자에 대한 메모리가 매핑되며 값의 할당은 선언 방식에 따라 다르게 이루어진다.

  • Variable Environment에는
    • var로 선언된 변수가 메모리에 매핑되며 초기값으로 undefined가 할당됩니다.
      선언형 함수가 메모리에 매핑되며 함수 전체가 메모리에 할당됩니다.
  • Lexical Environment에는
    • let, const로 선언된 변수가 변수가 메모리에 매핑되지만 초기값은 할당되지 않습니다.

2. Execution Phase
Creation 단계에서 코드 실행을 위한 환경 정보 값이 결정되었다면, Execution은 코드를 위에서 부터 읽으며 실행한다. 변수 값이 할당되는 코드가 실행 될 경우 Environment Record에 저장된 식별자 메모리에 값을 수정 또는 할당한다.

➡ js엔진이 코드를 실행(Execution Phase)하기 전 코드의 실행 환경 정보를 구축(Creation Phase)하는 것이 hoistind이 이루어지는 이유

0개의 댓글

관련 채용 정보