실행 컨텍스트(Execution Context)는 자바스크립트 동작의 기반이다.
this, 호이스팅처럼 JS에서 특이하게 느껴지는 대부분의 개념과 밀접하게 연결되어 있다.
1. 실행 컨텍스트란?
실행 컨텍스트는 ECMAScript 엔진이 코드의 실행 상태를 추적하기 위해 사용하는 내부 구조이다.
실행 컨텍스트는 항상 스택으로 관리되며, 새로운 코드(함수, 모듈 등)로 제어가 넘어가면 새로운 컨텍스트가 생성되고 스택에 쌓인다.
2. 실행 컨텍스트의 생성과 구조
자바스크립트 엔진은 코드를 실행하기 전에 평가(creation) 단계를 거쳐 실행 컨텍스트를 생성하고,
이후 실행(execution) 단계에서 코드를 실제로 수행한다.
✅ 평가 단계 (Creation Phase)
- 실행 컨텍스트 객체가 생성된다.
- LexicalEnvironment, VariableEnvironment, ThisBinding 등 이 설정된다.
- LexicalEnvironment: let, const, 함수 선언, 매개변수 등 포함
- VariableEnvironment: var 변수 바인딩 포함
- ThisBinding: 호출 방식 및 strict 모드 여부에 따라 결정됨
- var 변수는 선언과 동시에 undefined로 초기화됨 → 호이스팅 발생
- let, const 변수는 초기화되지 않은 채 선언됨 → 일시적 사각지대(TDZ)
- 함수 선언문은 함수 객체로 변환되어 미리 LexicalEnvironment에 저장됨
✅ 실행 단계 (Execution Phase)
- 코드가 한 줄씩 실행되며, 식별자 바인딩에 따라 실제 값이 할당됨
- 조건문, 함수 호출 등 로직 흐름 실행
- 현재 컨텍스트의 LexicalEnvironment에 없으면 OuterEnvironmentReference를 따라 탐색 → 스코프 체인 형성
- 전역까지 탐색 후에도 식별자가 없으면 ReferenceError
- 단, 비 strict 모드에서 var는 전역 객체에 프로퍼티처럼 추가될 수 있음
3. 실행 컨텍스트 구조 예시 (함수 기준)
function sum(x) {
var y = 3;
function InF() {
return;
}
return x + y;
}
sum(5);
위 코드에서 sum(5)가 호출되면 다음과 같은 실행 컨텍스트가 생성된다:
functionExecutionContext = {
VariableEnvironment: {
EnvironmentRecord: {
y: undefined // var 변수 호이스팅
},
outer: 글로벌 LexicalEnvironment
},
LexicalEnvironment: {
EnvironmentRecord: {
x: 5, // 매개변수
InF: <Function object> // 선언된 함수 객체
},
outer: 글로벌 LexicalEnvironment
},
ThisBinding: undefined, // strict mode 기준 (비 strict이면 전역 객체)
Function: sum, // 실행 중인 함수 객체
Realm: Realm(globalThis), // sum 함수가 속한 전역 환경
ScriptOrModule: ScriptRecord(main.js) // sum 함수가 정의된 스크립트
}
4. 실행 컨텍스트 구성 요소 요약
🔹 모든 실행 컨텍스트의 공통 요소 (사양 링크)
구성 요소 | 설명 |
code evaluation state | 코드 실행 위치 및 상태 (중단/재개 등) 추적 |
Function | 실행 중인 함수 객체 (전역/모듈이면 null) |
Realm | 현재 컨텍스트가 속한 Realm (전역 객체 및 내장 객체들의 묶음) |
ScriptOrModule | 해당 코드가 정의된 스크립트나 모듈 정보 |
🔹 ECMAScript 전용 요소 (ECMAScript 사양 링크)
구성 요소 | 설명 |
LexicalEnvironment | let, const, 함수 선언, 매개변수 등을 담고, 외부 참조를 위한 OuterEnvironmentReference 포함 |
VariableEnvironment | var 바인딩 전용 환경. 대부분의 경우 LexicalEnvironment와 같은 객체를 참조 |
PrivateEnvironment | 클래스 내부의 #private 필드/메서드 등 비공개 요소를 위한 전용 환경 |
🔹 ThisBinding (명세상 간접적으로 파생되는 구성)
실행 컨텍스트의 생성 시점에 함께 결정되며, ECMAScript 함수 실행 시 아래 기준에 따라 설정된다.
- 일반 함수:
- strict 모드: undefined
- 비 strict 모드: window (또는 globalThis)
- 화살표 함수:
- 자신의 실행 컨텍스트를 생성하지 않고, 외부 컨텍스트의 this 바인딩을 그대로 사용
- 클래스 메서드나 call/apply/bind와 함께 호출한 경우:
- 전달된 객체를 this로 바인딩함
5. 실행 컨텍스트의 생성 조건
다음과 같은 상황에서 실행 컨텍스트가 새로 만들어진다:
- 전역 코드 실행
- 함수 호출
- eval() 실행
- 모듈 import 및 실행
- async/await, generator 등의 재진입
이 과정에서 실행 컨텍스트 스택(Call Stack) 에 쌓이며, 가장 최근에 생성된 컨텍스트만 활성 상태가 된다.
6. 실행 컨텍스트와 접근 제한
실행 컨텍스트는 ECMAScript 사양에서 정의된 명세 전용 내부 구조다.
따라서 자바스크립트 코드에서는 직접 접근하거나 출력할 수 없다.
“An execution context is purely a specification mechanism... It is impossible for ECMAScript code to directly access or observe an execution context.” (ECMAScript 9.4)
참고자료
'FE > JS' 카테고리의 다른 글
자바스크립트 - 클로저 (1) | 2025.05.19 |
---|---|
JavaScript - this (0) | 2025.05.19 |
자바스크립트 호이스팅 정리 (1) | 2025.05.18 |
null, undefined, undeclared, NaN (1) | 2025.05.17 |
JavaScript: var, let, const (0) | 2025.05.13 |