이전 글에서는 실행 컨텍스트가 무엇인지, 어떻게 구성되는지 알아보았다!
이번에는 실행 컨텍스트의 생성 과정을 살펴보자.
0. 예시 코드
var var1 = "gvar1";
const const1 = "gconst1";
function first() {
var var1 = "fvar1";
var var2 = "fvar2"
const const1 = "fconst1";
function second() {
const const2 = "sconst2";
console.log(var1, var2, const1, const2);
}
second();
}
first();
1-1. 전역 코드 평가 - 생성 단계 (Creation Phase)
전역 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드: {
BindingObject(전역 객체 참조)
},
선언 환경 레코드: {
const1: < uninitialized >,
},
[[GlobalThisValue]]: Object,
},
외부 환경 참조: < null >
},
변수 환경 컴포넌트
}
전역 객체 = {
var1: undefined,
first: < func >,
/* ... */
}
- 실행 컨텍스트 생성, 콜스택에 push
- 렉시컬 환경 생성, 실행 컨텍스트에 바인딩
- 환경 레코드 생성 - 변수 선언(바인딩), var 초기화, 함수 선언문 초기화 및 할당, this 바인딩
- 외부 렉시컬 환경 참조 결정
- LEC, VEC 생성 및 렉시컬 환경 참조
1-2. 전역 코드 실행 - 실행 단계 (Execution Phase)
전역 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드: {
BindingObject(전역 객체 참조)
},
선언 환경 레코드: {
const1: "gconst1",
},
[[GlobalThisValue]]: Object,
},
외부 환경 참조: < null >
},
변수 환경 컴포넌트
}
전역 객체 = {
var1: "gvar1",
first: < func >,
/* ... */
}
변수 초기화
- const1 변수 초기화
순차적으로 값 할당, 함수 호출
- var1 변수 할당
- const1 변수 할당
- first() 함수 호출
- 순차적으로 실행되던 전역 코드의 실행을 일시 중단
- first() 함수 내부로 진입
2-1. first() 함수 코드 평가 - 생성 단계 (Creation Phase)
first 함수 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드,
선언 환경 레코드: {
var1: undefined,
var2: undefined,
const1: < uninitialized >,
second: < func >,
},
[[ThisValue]]: global,
},
외부 환경 참조: < 전역 실행 컨텍스트 >
},
변수 환경 컴포넌트
}
2-2. first() 함수 코드 실행 - 실행 단계 (Execution Phase)
first 함수 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드,
선언 환경 레코드: {
var1: "fvar1",
var2: "fvar2",
const1: "fconst1",
second: < func >,
},
[[ThisValue]]: global,
},
외부 환경 참조: < 전역 실행 컨텍스트 >
},
변수 환경 컴포넌트
}
변수 초기화
- const1 변수 초기화
순차적으로 값 할당, 함수 호출
- var1 변수 할당
- var2 변수 할당
- const1 변수 할당
- second() 함수 호출
- 순차적으로 실행되던 first()의 실행을 일시 중단
- second() 함수 내부로 진입
3-1. second() 함수 코드 평가 - 생성 단계 (Creation Phase)
second 함수 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드,
선언 환경 레코드: {
const2: < uninitialized >,
},
[[ThisValue]]: global,
},
외부 환경 참조: < first 함수 실행 컨텍스트 >
},
변수 환경 컴포넌트
}
3-2. second() 함수 코드 실행 - 실행 단계 (Execution Phase)
second 함수 실행 컨텍스트 = {
렉시컬 환경 컴포넌트: {
환경 레코드: {
객체 환경 레코드,
선언 환경 레코드: {
const2: "sconst2",
},
[[ThisValue]]: global,
},
외부 환경 참조: < first 함수 실행 컨텍스트 >
},
변수 환경 컴포넌트
}
변수 초기화
- const2 변수 초기화
순차적으로 값 할당, 함수 호출
- const2 변수 할당
- console.log(var1, var2, const1, const2); 호출
- 식별자 검색
- var1 - second 함수 실행 컨텍스트의 렉시컬 환경의 환경레코드에 var1이 없으므로 외부 환경 참조로 first 함수 실행 컨텍스트에서 찾기 -> "fvar1"
- var2 - second 함수 실행 컨텍스트의 렉시컬 환경의 환경레코드에 var2가 없으므로 외부 환경 참조로 first 함수 실행 컨텍스트에서 찾기 -> "fvar2"
- const1 - second 함수 실행 컨텍스트의 렉시컬 환경의 환경레코드에 const1이 없으므로 외부 환경 참조로 first 함수 실행 컨텍스트에서 찾기 -> "fconst1"
- const2 - second 함수 실행 컨텍스트의 렉시컬 환경의 환경레코드에 const2 확인 -> "sconst2"
4. second() 함수 코드 실행 종료
- 콜스택에서 second 함수 실행 컨텍스트 pop
- second 함수의 렉시컬 환경까지 즉시 소멸하는 것은 아니다! (가비지 컬렉션에 따름)
5. first() 함수 코드 실행 종료
- 콜스택에서 first 함수 실행 컨텍스트 pop
6. 전역 코드 실행 종료
- 콜스택에서 전역 실행 컨텍스트 pop
'TIL > JavaScript' 카테고리의 다른 글
[240203] 클로저 (0) | 2024.02.03 |
---|---|
[240130] this (0) | 2024.01.30 |
[240130] 렉시컬 환경, 렉시컬 스코프 (1) | 2024.01.30 |
[240130] 스코프, 스코프 체인, 프로토타입, 프로토타입 체인 (0) | 2024.01.30 |
[240130] 자바스크립트의 객체 생성 방법(객체 리터럴 vs new Object() vs 생성자 함수 vs 클래스) (1) | 2024.01.30 |