ExecutionContext {
GlobalExecutioncontext
FunctionalExecutionContext
EvalFunctionExecutionContext // 보안에 문제있어서 이젠 거의 안씀
}
Global Execution Context
├─ LexicalEnvironment
│ ├─ EnvironmentRecord (GlobalDeclarative + GlobalObject)
│ └─ Outer = null
├─ VariableEnvironment
└─ ThisBinding = global object (browser=window, node=global)
Function Execution Context
├─ LexicalEnvironment (FunctionEnvironmentRecord)
│ ├─ EnvironmentRecord (Declarative)
│ │ 매개변수, let/const/var, 함수 선언 저장
│ └─ Outer = 함수 선언 위치의 Environment
├─ VariableEnvironment (거의 동일한 기록용 Env)
└─ ThisBinding (call/apply/bind 또는 default undefined)
함수 호출시 내부변수는 lexicalEnvironment의 Envrecord에 저장
EC는 사라지지만 EnvironmentRecord는 클로저에 의해 살아남을 수 있음
클로저의 본질: FunctionObject.[[Environment]]에 이 EnvironmentRecord가 embed되는 것
FunctionObject가 EnvironmentRecord를 캡쳐해서 [[Environment]]에 저장
다음의 동작이 다른 이유
function foo() {
}
const a = foo();
const b = foo();
console.log(a === b) // true
Global Execution Context (Create Phase)
Lexical Env: (Global)
foo -> Functional Object(foo)
Outer: null
VariableRecord: (Global)
Call Stack (Execution Phase)
a = foo()
Execution Context #1(foo call)
Lexical Env: (FooEnv #1)
EnvironmentRecord: {}
Outer: Global
ThisisBinding: undifiend
VariableEnv: (FooEnv #1)
foo returns undefined
Call Stack
b = foo()
Execution Context #2
Lexical Env: (FooEnv #2)
EnvironmentRecord: undefined
Outer: Global
ThisisBinding: undifiend
VariableEnv: (FooEnv #2)
foo returns undefined
a === b
undefined === undefined → true
function foo() {
let x = 1;
return function inner() {
console.log(x++);
}
}
const a = foo();
const b = foo();
console.log(a === b); // false
a(); // 1
a(); // 2
b(); // 1
Global Execution Context (Create Phase)
Lexical Env: (Global)
EnvironmentRecord:
foo -> Functional Object(foo)
Outer: null
Variable Env: (Global)
Call Stack (Execution Phase)
a = foo()
Execution Context #1(foo call)
Lexical Env: (FooEnv #1)
EnvironmentRecord:
x = 1
Outer: Global
ThisisBinding: undifiend
VariableEnv: (FooEnv #1)
inner #1 생성(literal 평가)
inner #1.[[Environment]] = FooEnv #1 클로저 형성
a = inner#1
Call Stack (Execution Phase)
b = foo()
Execution Context #2
Lexical Env: (FooEnv #2)
EnvironmentRecord:
x = 1
Outer: Global
ThisisBinding: undifiend
VariableEnv: (FooEnv #2)
inne r#2 생성(literal 평가)
inner #2.[[Environment]] = FooEnv #2 클로저 형성
b = inner #2
a === b
inter#1 === inter#2 ->false
반환값이 primitive라면 [[Environment]]는 외부에 전달되지 않는다.
클로저가 있을 때만 FunctionObject 내부에 Env가 embed된다.
이래서 JS가 인터프리터 언어구나
'프론트엔드 관련 > 기초' 카테고리의 다른 글
| FSD에서 도메인 중심 아키텍처로 전환하며 마주한 현실적인 선택들 (3) | 2026.01.04 |
|---|---|
| Zustand 역설계 (0) | 2025.12.14 |
| tanstack query 개선기 (0) | 2025.12.07 |
| React Router Path AutoComplete with type-safety (4) | 2025.04.10 |
| [React] http Typescript axios(feat. interceptor 에러 핸들링) (0) | 2025.03.30 |