JavaScript/AboutJS

[JavaScript] 실행 컨텍스트 ( Execution Context )

머지?는 병합입니다 2024. 4. 24. 23:50

Execution Context (실행 컨텍스트) 란?

 

자바스크립트의 실행 환경을 추상화한 개념으로,
코드(함수)가 실행되기 위해 필요한 환경 정보를 담고 있는 객체이다.

 

 

1. 구성 요소

 

  1. Lexical Environment
    원래는 스코프 체인클로저를 구현하기 위해 도입되었으며, let const 가 도입되면서
    Lexical Environment의 역할이 확장되었다.
    Variable Environment를 포함하며, let const 변수와 블록 스코프 내의 함수 선언을 저장한다.(Environment Record)
    또한 외부 환경에 대한 참조도 포함한다.(ounter environment reference)
    이들은 블록 스코프를 가지며, 더 세밀한 스코프 제어를 가능하게 했다.

  2. Variable Environment
    Lexical Environment 안에 포함된 특별한 형태로, var로 선언된 변수들을 저장한다.

    전역 스코프나 함수 스코프에서의 함수 선언을 저장한다

  3. ThisBinding:
    현재 context에서 this 키워드가 참조하는 객체를 결정 ( 추후에 설명 )

 

 

2. Lexical Environment 와 Variable Environment 의 구체적인 차이

 

  1. 변수 선언 방식:
    • Variable Environment: 주로 var로 선언된 변수를 저장
    • Lexical Environment: let과 const로 선언된 변수를 저장
  2. 호이스팅 동작:
    • Variable Environment: var 변수는 선언과 동시에 undefined로 초기화
      이로 인해 변수를 선언 전에 접근해도 undefined를 반환한다.
    • Lexical Environment: let과 const 변수는 선언만 호이스팅되고 초기화는 되지 않는다.
      따라서 선언 전에 접근하면 ReferenceError가 발생 (일명 "Temporal Dead Zone")
   console.log(x); // ReferenceError
   let x = 5;

 

  3. 스코프 처리:

  1. Variable Environment: 함수 스코프를 가진다.
    즉, if 블록이나 for 루프 내에서 선언해도 해당 함수 전체에서 접근 가능
  2. Lexical Environment: 블록 스코프를 가진다.
    변수가 선언된 블록 내에서만 접근 가능

4. 재선언:

  • Variable Environment: 같은 스코프 내에서 var로 변수를 재선언할 수 있다.
  • Lexical Environment: 같은 스코프 내에서 let이나 const로 변수를 재선언하면 SyntaxError가 발생.

 


5. 글로벌 객체에 추가:

  • Variable Environment: 글로벌 스코프에서 var로 선언한 변수는 글로벌 객체(브라우저에서는 window)의 프로퍼티가 된다.
  • Lexical Environment: let과 const로 선언한 변수는 글로벌 스코프에 있더라도 글로벌 객체의 프로퍼티가 되지 않는다.



6. 환경 갱신:

  • Variable Environment: 주로 초기 상태를 나타내며, 실행 중에 크게 변하지 않는다.
    - 주로 함수가 생성될 때의 "스냅샷"과 같다.
    - 함수가 정의될 때 생성되며, 그 함수가 호출될 때마다 같은 상태로 유지된다.
    - 변수의 값은 변할 수 있지만, 변수 자체의 바인딩은 변하지 않는다.
  • Lexical Environment: 코드 실행 중 지속적으로 갱신될 수 있다.
    - 코드 블록(예: if 문, for 루프 등)이 실행될 때마다 새로 생성될 수 있다.
    - 새로운 블록이 시작될 때마다 새로운 Lexical Environment가 생성되고, 블록이 끝나면 제거된다.
    - 이로 인해 블록 스코프가 가능해지고, 변수의 생명주기가 더 정확하게 관리된다.
function example() {
    var a = 1;  // Variable Environment에 저장
    
    if (true) {
        let b = 2;  // 새로운 Lexical Environment에 저장
        const c = 3;  // 같은 Lexical Environment에 저장
        
        console.log(a, b, c);  // 1, 2, 3
    }
    
    console.log(a);  // 1
    console.log(b);  // ReferenceError: b is not defined
}

 

  • a는 함수의 Variable Environment에 저장되며, 함수 전체에서 접근 가능.
  • b와 c는 if 블록의 Lexical Environment에 저장된다. 이 환경은 블록이 시작될 때 생성되고 블록이 끝날 때 제거된다.

"갱신"이라는 표현은 새로운 Lexical Environment가 생성되고 제거되는 과정을 의미한다. 반면 Variable Environment는 함수가 생성될 때 한 번 만들어지고, 그 구조가 크게 변하지 않는다.

 

 

 

3. Lexical Environment (어휘적 / 사전적 환경)

 

 

Environment Record 와 Outer Environment Reference 로 구성되어 있으며

실행 컨텍스트를 구성하는 환경 정보들을 모아 사전처럼 구성한 객체를 의미한다.

 

내부식별자 a : 10

내부식별자 b : 20

외부 정보      : A를 참조한다 

위의 예시가 위 사진에서 보았던 Environment Record 와 outer environment reference 에 담긴 정보이다.

 

내부식별자 a : 10 ( Environment Record )

내부식별자 b : 20 ( Environment Record )

외부 정보      : A를 참조한다  ( outer environment reference )



1. Environment Record 

 

실행 컨텍스트가 최초 실행될 때, 가장 먼저하는 일이 현재 문맥의 식별자 정보가 수집하여

Environment Record 에 담게 되는 데, 이게 흔히 들어 본 호이스팅(hoisting) 이다.

 

호이스팅은 실제로 일어나는 특정한 현상이 아닌 Environment Record 에 정보를 담는 과정을

관념적으로 일컷는 단어이다.

console.log(a());
console.log(b);
console.log(c);

function a() {
  return 'a';
}

var b = 10;

var c = 20;

 

이렇게 코드가 있다고 하면 아래처럼 먼저 함수 선언문과 변수들의 정보를 먼저 읽어오게 된다.

이건 호이스팅의 설명에서 쉽게 볼 수 있는 가상의 관념적인 예시인데

function a() {
  return 'a';
}
var b;
var c;
// =======================

console.log(a());
console.log(b);
console.log(c);

b = 10;
c = 20;

 

실행 컨텍스트가 생성되는 순간에 제일 먼저 하는 일이 Environment Record 에

함수 선언문과 변수들의 정보를 코드 순서대로 가져오는 것이고, 

이것은 호이스팅에서 이야기하는 것과 같은 개념이 되는 것이다.


environmentRecord {

  function a() { ... },

  b: undefined,

  c: undefined,

}

 

 

2. Outer Environment Reference

상위 스코프의 정보를 담고 있다.

 

 

스코프라는 것은 러프하게 이야기하자면 변수의 유효범위라고 할 수 있는데,

이 유효범위를 만드는 것이 실행 컨텍스트 이다.

실행 컨텍스트가 수집한 정보만 접근이 가능하고,  그 변수는 실행 컨텍스트 내부에서만 

존재를 하는 것이기 때문이다.

 

그리고 이 Outer Environment Reference 에서는 상위 스코프의 Lexical Environment 에 대한 

정보를 가지고 있기 때문에, 제일 작은 스코프인 inner 스코프에 특정 행위를 위한 변수가 없다면
그 상위 스코프로 outer 에 가서 필요한 변수를 찾고 outer 에도 없다면 global 에서 찾을 수 있는 것이다. 

이렇게 스코프들이 Outer Environment Reference 를 통해 서로 엮여 있는 것 처럼 동작하는 것을

스코프 체인( Scope Chain) 이라고 한다.

 

당연한 이야기지만 상위 스코프에 대한 정보는 있지만, 하위 스코프에 대한 정보는 가지고 있지 않으므로,

상위에서 하위로는 접근을 할 수 없다.

 

정리하자면

실행 컨텍스트란 코드(함수)가 실행되기 위해 필요한 환경 정보를 담고 있는 객체인데,

  • lexical environment 
  • variable environment
  • this binding
    이라는 게 있다

lexical environmentvariable environment 안에는

  • Environment Record 
  • Outer Environment Reference 
    가 있는데

Environment Record 에는 함수 선언문과 변수의 정보가 담겨 있으며 

이는 호이스팅의 개념이다

 

Outer Environment Reference는 외부 스코프에 대한 정보가 담겨 있으며

이는 스코프 체인과 연관이 있다.

로 정리할 수 있다.

 

아쉽지만 개발자 도구 등으로 실행 컨텍스트나 그 안에 포함되는 Lexical Environment 에 직접 액세스하거나 조작하는 것은 불가능하며,  "이런 개념은 어디까지나 순수한 메커니즘에 불과하다"고 하여, 모든 자바스크립트 엔진이 "정확히 이렇게 동작하도록 구현되어 있어야만 한다"는 식의 강제성이 없음을 명시하고 있다. 
https://tc39.es/ecma262/#sec-execution-contexts

https://tc39.es/ecma262/#sec-lexical-environments


정재남 님의 코어 자바스크립트 강의를 바탕으로 정리한 내용입니다

 

다음 연관 페이지 :
자바스크립트의 This

https://daunje0.tistory.com/84

 

[JavaScript] This 를 판단하는 기준

이글은 실행 컨텍스트에서 넘어왔습니다.https://daunje0.tistory.com/61 [JavaScript] 실행 컨텍스트 ( Execution Context )Execution Context (실행 컨텍스트) 란? 자바스크립트의 실행 환경을 추상화한 개념으로,

daunje0.tistory.com

 

클로져 closure

https://daunje0.tistory.com/90

 

[JavaScript] Closure (클로져)

클로저(Closure)는 1. 내부 함수와2. 그 함수가 선언될 때의 렉시컬 환경(Lexical Environment)의 조합 이다. 1. 내부 함수: 다른 함수 내부에 정의된 함수2. 렉시컬 환경: 함수가 선언될 때 생성되는 환경

daunje0.tistory.com