<모던 자바스크립트 Deep Dive> 23장 실행 컨텍스트 요약
23. 실행 컨텍스트
1) 소스코드의 타입
- 소스코드는 4가지 타입으로 구분되는데, 이들은 실행 컨텍스트를 각각 생성함
1. 전역 코드 : 전역 변수를 관리하기 위해 최상위 스코프인 전역 스코프를 생성
2. 함수 코드 : 지역 스코프를 생성하고, 이를 스코프 체인에 연결
3. eval 코드 : strict mode에서 독자적인 스코프 생성
4. 모듈 코드 : 모듈별로 독립적인 모듈 스코프 생성
2) 소스코드의 평가와 실행
- 소스코드는 소스코드의 평가, 소스코드의 실행 2가지 과정으로 나뉘어 처리됨
- 소스코드의 평가 과정에서는 실행 컨텍스트를 생성하고 생성된 변수나 함수 식별자를 키로써 스코프에 등록
- 소스코드의 실행 과정에서는 선언문을 제외한 소스코드를 순차적으로 실행하며, 실행에 필요한 정보를 검색하여 취득하고, 실행 결과는 스코프에 다시 등록됨
3) 실행 컨텍스트의 역할
- 코드가 실행되며련 스코프, 식별자, 코드 실행 순서 등의 관리가 필요
- 생성된 모든 식별자의 스코프를 구분하여 등록, 상태변화를 지속적으로 관리, 스코프 체인을 형성, 실행 중인 코드의 순서를 변경하거나 되돌아감
- 자바스크립트 엔진의 소스코드 평가와 실행 과정
1. 전역 코드 평가
- 전역 코드 실행에 앞서 전역 코드를 평가함
- 선언문만 먼저 실행
- 생성된 전역 변수와 전역 함수는 전역 스코프에 등록
- var 키워드로 선언된 전역 변수와, 함수 선언문으로 정의된 전역 함수는 전역 객체의 프로퍼티와 메서드가 됨
2. 전역 코드 실행
- 코드 평가 과정이 마치면 런타임이 시작됨
- 순차적으로 코드를 실행하며, 값이 할당되고 함수가 호출됨
3. 함수 코드 평가
- 전역 코드 실행 중 함수를 만났을 때 시작
- 매개 변수와 지역 변수 선언문이 먼저 실행되고, 생성된 매개변수와 지역변수는 지역 스코프에 등록됨
- arguments 객체가 생성되어 지역 스코프에 등록, this 바인딩도 결정
4. 함수 코드 실행
- 함수 코드 평가 과정이 마치면 런타임이 시작됨
- 순차적으로 코드를 실행하며, 값이 할당되고 console.log 메서드가 호출됨
4) 실행 컨텍스트 스택
- 코드 평가의 단계에서 생성되는 실행 컨텍스트는 스택 자료구조로 관리되는데 이를 실행 컨텍스트 스택이라 함
- 코드의 실행 순서를 관리
- 실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트는 언제나 현재 실행 중인 코드의 실행 컨텍스트이며 이를 실행 중인 실행 컨텍스트라 함
5) 렉시컬 환경
- 식별자와 식별자에 바인딩된 값, 상위 스코프에 대한 참조를 기록하는 자료구조로서 실행 컨텍스트를 구성하는 컴포넌트
- 스코프와 식별자를 관리
- 키와 값을 갖는 객체 형태의 스코프를 생성하여 식별자를 키로 등록, 바인딩된 값을 관리
- 두 개의 컴포넌트로 구성
1. 환경 레코드 : 식별자를 등록하고 식별자에 바인딩된 값을 관리하는 저장소
2. 외부 렉시컬 환경에 대한 참조 : 상위 스코프를 가리키며, 스코프 체인을 구현
6) 실행 컨텍스트의 생성과 식별자 검색 과정
1. 전역 객체 생성
- 전역 객체는 코드가 평가되기 이전에 생성됨
2. 전역 코드 평가
- 소스코드 로드 후 전역 코드가 평가됨
- 전역 실행 컨텍스트 생성(실행 중인 실행 컨텍스트가 됨) -> 전역 렉시컬 환경 생성(생성 후 전역 실행 컨텍스트에 바인딩) -> 전역 환경 레코드 생성(객체 환경 레코드, 선언적 환경 레코드로 구분하며 이들은 서로 협력하여 전역 스코프와 전역 객체를 관리) -> 객체 환경 레코드 생성(BindingObject 객체와 연결되어 전역 객체의 프로퍼티와 메서드가 됨) -> 선언적 환경 레코드 생성(앞에서 등록되지 않은, let과 const 키워드로 선언한 전역 변수를 등록) -> this 바인딩([[GlobalThisValue]] 내부 슬롯에 this를 바인딩) -> 외부 렉시컬 환경에 대한 참조 결정(상위 스코프, 스코프 체인 구현)
3. 전역 코드 실행
- 전역 코드를 순차적으로 실행
- 어느 스코프의 식별자를 참조하면 되는지 결정하는 식별자 결정이 이루어짐
- 식별자 결정은 실행 중인 실행 컨텍스트에서 식별자 검색을 시작함
4. 함수 코드 평가
- 함수 실행 컨텍스트 생성 -> 함수 렉시컬 환경 생성 -> 함수 환경 레코드 생성(매개변수, arguments 객체, 함수 내부에서 선언한 지역 변수 및 중첩 함수를 등록하고 관리) -> this 바인딩([[ThisValue]] 내부 슬롯에 바인딩]] -> 외부 렉시컬 환경에 대한 참조 결정(함수를 어디서 정의했는지에 따라 상위 스코프 결정)
5. 함수 코드 실행
- 식별자 결정을 위해 실행 중인 실행 컨텍스트의 렉시컬 환경에서 식별자 검색을 시작함
6. console.log 실행
- console 식별자 검색 -> log 메서드 검색(console 객체에서 검색) -> 표현식의 평가 -> console.log 메서드 호출(평가하여 생성한 값을 메서드에 전달하여 호출)
7. 함수 코드 실행 종료
- 객체를 포함한 모든 값은 참조되고 있지 않을 때 가비지 컬렉터에 의해 소멸함
- 실행 컨텍스트는 종료되어 소멸되더라도, 렉시컬 환경을 누군가가 참조하고 있다면 렉시컬 환경은 소멸하지 않음
참고 : 도서 <Deep Dive 모던 자바스크립트>