23.1. 소스코드의 타입
1. 전역 코드
- 전역 변수를 관리하기 위해 최상위 스코프인 전역 스코프를 생성함
- 전역 실행 컨텍스트 생성
2. 함수 코드
- 지역 스코프를 생성하고, 전역 스코프에서 시작하는 스코프 체인으로 연결해야 함
- 함수 실행 컨텍스트 생성
3. eval 코드
- strict mode에서 자신만의 독자적인 스코프 생성
- eval 실행 컨텍스트 생성
4. 모듈 코드
- 모듈별로 독립적인 모듈 스코프 생성
- 모듈 실행 컨텍스트 생성
23.2. 소스코드의 평가와 실행
소스코드 평가
- 실행 컨텍스트 생성
- 변수, 함수 등의 선언문 먼저 실행하여 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록
소스코드 실행
- 평가 이후 선언문을 제외한 소스코드가 순차적으로 실행됨 (런타임)
- 실행 컨텍스트가 관리하는 스코프에서 변수나 함수의 참조를 검색하여 취득함
- 실행 결과는 실행 컨텍스트가 관리하는 스코프에 등록함

23.3. 실행 컨텍스트의 역할
- 소스코드 실행 순서
- 전역 코드 평가: 선언문 먼저 실행, 전역 스코프 등록 등
- 전역 코드: 런타임 시작, 전역 코드 순차적 실행, 값 할당 및 함수 호출 등
- 함수 코드 평가: 함수 내부의 매개 변수와 지역 변수 선언문 실행 및 지역 스코프 등록, this 바인딩 결정 등
- 함수 코드 실행: 함수 코드 순차적 실행, 매개 변수와 지역 변수 값 할당 및 console.log 메서드 호출
- 실행 컨텍스트의 역할
- 코드 실행을 위해 스코프, 식별자, 코드 실행 순서 등의 관리가 필요함
- 모든 식별자(변수, 함수, 클래스 등)의 스코프를 구분하여 등록하고 상태 변화(바인딩 값 변화)를 지속 관리해야 함
- 스코프는 중첩 관계에 의해 스코프 체인 형성해야 함
- 현재 실행 중인 코드의 실행 순서를 변경하거나 되돌아갈 수 있어야 함
- 이를 관리하는 것이 실행 컨텍스트
- 소스코드를 실행하기 위한 환경과 실행 결과를 실제로 관리하는 영역
- 식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리함
- 코드 실행 순서는 실행 컨텍스트 스택으로 관리함
23.4. 실행 컨텍스트 스택
- 실행 컨텍스트 스택: 스택(stack, LIFO 후입선출) 자료구조 관리
- 전역 코드의 평가와 실행
- 외부 함수 코드의 평가와 실행
- 중첩 함수 코드의 평가와 실행
- 외부 함수 코드로 복귀
- 전역 코드로 복귀
- 코드 실행 순서 관리
- 실행 중인 실행 컨텍스트 (running execution context): 최상위 실행 컨텍스트는 항상 현재 실행 중인 코드의 실행 컨텍스트
23.5. 렉시컬 환경
- 식별자와 바인딩 값, 상위 스코프 참조를 기록하는 자료 구조
- 실행 컨텍스트를 구성하는 컴포넌트
- 스코프를 구분하여 식별자를 등록하고 관리하는 저장소 역할
- 렉시컬 환경의 구성 컴포넌트
- 환경 레코드: 스코프에 포함된 식별자를 등록하고 바인딩 값을 관리하는 저장소
- 외부 렉시컬 환경에 대한 참조: 상위 코드의 렉시컬 환경 (상위 스코프)
23.6. 실행 컨텍스트의 생성과 식별자 검색 과정
23.6.1. 전역 객체 생성
23.6.2. 전역 코드 평가
1. 전역 실행 컨텍스트 생성
2. 전역 렉시컬 환경 생성
- 전역 렉시컬 환경을 생성하고 전역 실행 컨텍스트에 바인딩함
2.1. 전역 환경 레코드 생성
- 전역 변수를 관리하는 전역 스코프, 전역 객체의 빌트인 전역 프로퍼티와 빌트인 전역 함수 표준 빌트인 객체 제공
- 2.1.1. 객체 환경 레코드 생성
BindingObject 객체(전역 객체)와 연결
- 전역 객체의 프로퍼티와 메서드
- var 키워드 전역 변수
- 함수 선언문 전역 함수
- 2.1.2. 선언적 환경 레코드 생성
2.2. this 바인딩
- 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에
this 바인딩
2.3. 외부 렉시컬 환경에 대한 참조 결정
- 소스코드의 렉시컬 환경(상위 스코프)을 가리킴 -> 단방향 링크드 리스트인 스코프 체인
- 전역 코드의 외부 소스코드는 없으므로 null 할당
23.6.3. 전역 코드 실행
- 전역 코드 순차적 실행
- 변수 할당문 실행
- 함수 호출 -> 식별자 검색 및 결정: 어느 스코프의 식별자를 참조할 지 결정
23.6.4. 외부 함수 평가
- 전역 코드 실행 일시 중단
- 함수 내부로 제어권 이동
- 함수 코드 평가
- 함수 실행 컨텍스트 생성
- 함수 렉시컬 환경 생성
- 2.1. 함수 환경 레코드 생성
- 2.2. this 바인딩
- 2.3. 외부 렉시컬 환경에 대한 참조 결정
-> 함수를 어디서 정의했는지에 따라 상위 스코프 결정
23.6.5. 외부 함수 실행
- 함수 코드 순차적 실행
- 매개변수에 인수 할당 및 변수 할당문 실행
- 식별자 검색 및 결정
23.6.6. 중첩 함수 평가
- 중첩 함수 내부로 제어권 이동
- 외부 함수 평가 과정과 동일
23.6.7. 중첩 함수 실행
- 런타임 시작, 함수 코드 순차적 실행
- 매개변수에 인수 할당 및 변수 할당문 실행
- 내부에 선언된 메서드 호출 실행
23.6.8. 중첩 함수 실행 종료
- 중첩 함수 실행 종료
- 스택에서 해당 실행 컨텍스트 제거 및 외부 함수로 이동
- 렉시컬 환경이 즉시 소멸되는 것은 아님
- 모든 참조가 없어지면 가비지 컬렉터에 의해 메모리 공간 확보 해제 및 소멸
23.6.9. 외부 함수 실행 종료
- 외부 함수 실행 종료
- 스택에서 해당 실행 컨텍스트 제거 및 전역 코드로 이동
23.6.10. 전역 코드 실행 종료
- 전역 코드 실행 종료
- 스택에서 전역 실행 컨텍스트 제거 -> 실행 컨텍스트 스택 비워짐
23.7. 실행 컨텍스트와 블록 레벨 스코프
- var 키워드: 함수 레벨 스코프
- let, const 키워드: 블록 레벨 스코프
- 모든 코드 블록을 지역 스코프로 인정
- let, const 키워드를 사용한 블록문이 실행될 때마다 코드 블록을 위한 새로운 독립적인 렉시컬 환경을 생성하여 식별자의 값을 유지함
[출처] 모던 자바스크립트, Deep Dive