[JavaScript] 실행 컨텍스트 ( Execution Context )
Execution Context (실행 컨텍스트) 란?
자바스크립트의 실행 환경을 추상화한 개념으로,
코드(함수)가 실행되기 위해 필요한 환경 정보를 담고 있는 객체이다.
1. 구성 요소
- Lexical Environment
원래는 스코프 체인과 클로저를 구현하기 위해 도입되었으며, let const 가 도입되면서
Lexical Environment의 역할이 확장되었다.
Variable Environment를 포함하며, let const 변수와 블록 스코프 내의 함수 선언을 저장한다.(Environment Record)
또한 외부 환경에 대한 참조도 포함한다.(ounter environment reference)
이들은 블록 스코프를 가지며, 더 세밀한 스코프 제어를 가능하게 했다. - Variable Environment
Lexical Environment 안에 포함된 특별한 형태로, var로 선언된 변수들을 저장한다.
전역 스코프나 함수 스코프에서의 함수 선언을 저장한다 - ThisBinding:
현재 context에서 this 키워드가 참조하는 객체를 결정 ( 추후에 설명 )
2. Lexical Environment 와 Variable Environment 의 구체적인 차이
- 변수 선언 방식:
- Variable Environment: 주로 var로 선언된 변수를 저장
- Lexical Environment: let과 const로 선언된 변수를 저장
- 호이스팅 동작:
- Variable Environment: var 변수는 선언과 동시에 undefined로 초기화
이로 인해 변수를 선언 전에 접근해도 undefined를 반환한다. - Lexical Environment: let과 const 변수는 선언만 호이스팅되고 초기화는 되지 않는다.
따라서 선언 전에 접근하면 ReferenceError가 발생 (일명 "Temporal Dead Zone")
- Variable Environment: var 변수는 선언과 동시에 undefined로 초기화
console.log(x); // ReferenceError
let x = 5;
3. 스코프 처리:
- Variable Environment: 함수 스코프를 가진다.
즉, if 블록이나 for 루프 내에서 선언해도 해당 함수 전체에서 접근 가능 - 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 environment 과 variable 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