Execution Context의 구성
- Lexical Environment : 식별자와 스코프 관리
- Execution Context Stack (Call Stack) : 코드 실행 순서 관리
Execution Context Stack : Code의 실행 순서 관리
코드가 실행되는 순서에 따라 Execution Context가 stack에 push, pop하면서 코드 실행 순서를 관리한다.
- Global code
- JS Engine은 Global code를 평가하고 이로부터 global execution context를 생성해 Stack에 push한다.
- 이 때 Global scope에 해당되는 property, method들은 global execution context에 등록된다. 따라서 Stack에 global scope에 해당되는 entity들이 stack에 같이 들어가있다.
- function call
- 함수 호출 시 global code의 흐름을 멈추고 호출된 함수 내부로 이동된다. (코드의 제어권 이동)
- JS Engine은 function code를 평가해 function execution context를 생성하고 execution context stack에 push한다.
- 만일 함수 내에 다른 함수가 정의되어 있는 형태라면 해당 함수도 똑같이 평가, push 등의 작업이 이루어진다.
- function end
- 함수 종료 시 코드의 제어권을 상위 스코프로 넘기고 JS Engine에 의해 execution context stack에서 해당 함수의 execution context가 pop된다.
- end
- Stack 내부에서 Global execution context 위에 쌓여있던 context들이 모두 실행이 완료되면 global code로 돌아온다.
- global code의 실행이 종료되면 global execution context도 call stack에서 pop되어 execution context는 empty상태가 된다.
따라서 Execution context stack은 코드의 실행 순서를 관리한다.
또한 stack의 top은 항상 현재 실행중인 코드의 execution context이다.
Running Execution Context : execution context stack의 top에 위치한 execution context
Lexical Environment : Scope, Identifier 관리
-
Lexical Environment
- Execution context를 구성하는 component
- 식별자와 식별자에 바인딩된 값, 상위 스코프에 대한 참조를 기록하는 자료구조
- key, value를 갖는 객체 형태의 스코프를 생성해 identifier를 key로 등록하고 바인딩된 값을 관리
-> Lexical scope의 실체
- lexical scope? : scope를 구분해 identifier를 등록하고 관리하는 저장소
-
Execution context : Lexical Environment Component와 Variable Environment Component으로 구성
-
생성 초기에 Lexical Environment Component와 Variable Environment Component는 동일한 lexical environment를 참조하지만 상황에 따라 Variable Environment를 위한 새로운 lexical 환경이 생성되는 등 두 component의 내용이 달라질 수 있음
Lexical Environment의 구성요소
- Environment Record
- Scope에 포함된 식별자를 등록하고, 등록된 식별자에 바인딩된 값을 관리하는 저장소
- source code type에 따라 관리 내용이 다름
- Outer Lexical Environment Reference
- 외부 렉시컬 환경의 참조는 상위 스코프를 가리킴 (해당 execution context를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경)
- Outer Lexical Environment Reference를 통해 단방향 연결 리스트 구조를 가진 스코프 체인 구현
Execution Context의 생성과 Identifier 검색 과정
- Global Object 생성
- Global code 평가 전에 생성
- Built-in 전역 프로퍼티와 전역 함수, 표준 빌트인 객체 추가
- Web API 또는 특정 환경을 위한 host 객체 포함
- Global Code 평가 : 소스 코드가 로드되면 JS Engine에 의해 전역 코드가 평가
- Global Execution context 생성
- Global Lexical Environment 생성
- Global Environment Record 생성
- Object Environment Record(객체 환경 레코드) 생성
- Declarative Environment Record(선언적 환경 레코성 생성
- this 바인딩
- 외부 렉시컬 환경에 대한 참조 결정
- Globla Code 실행
- 전역 코드의 순차적 실행, 변수 할당 시작
- 식별자 결정 : 어느 스코프에 있는 식별자를 참조할 것인지 결정
- 스코프 체인의 동작 원리
- 실행 중인 Execution context에서 식별자 검색 시작
- 선언된 식별자는 Execution context의 렉시컬 환경의 환경 레코드에 등록됨
- 실행 중인 Execution context에서 식별자를 찾을 수 없으면 상위 스코프로 이동해 검색
(외부 렉시컬 환경에 대한 참조가 가리키는 렉시컬 환경)
- Function code 평가 : Global code 실행 일시 중단, 함수 내부로 코드 제어권 이동
- Function Execution context 생성
- 생성된 Function execution context는 function lexical environment가 완성된 다음 execution context stack에 push됨.
- execution context stack의 최상위에 위치함 (running execution context)
- Function Lexical Environment 생성
- function lexical environment를 생성하고 function execution context에 바인딩함.
- 렉시컬 환경은 환경 레코드와 외부 렉시컬 환경에 대한 참조로 구성
- Function Environment Record 생성
- 매개변수, arguments 객체, 지역변수, 중첩 함수 등록 및 관리
- this 바인딩
- 함수 환경 레코드 내 this 바인딩
- 일반 함수로 호출되었을 경우 전역 객체를 가리킴
- 외부 렉시컬 환경에 대한 참조 결정
- 함수의 정의가 평가된 시점에 running execution context의 렉시컬 환경의 참조 할당
- 일반 함수는 전역 코드 평가 시점에 평가되므로 이 시점의 running execution context는 global execution context임
- 전역 함수의 경우 외부 렉시컬 환경에 대한 참조는 전역 렉시컬 환경의 참조가 할당됨
- Function code 실행
- Function code 실행 종료
- 현재 실행 중인 함수가 종료되면 execution context stack에서 function execution context가 pop되어 running execution context가 변경됨
- Global code 실행 종료
- call stack에서 global execution context를 제외한 모든 context가 모두 pop된 후 global code도 모두 실행이 종료되면 global execution context도 execution context stack에서 pop되어 stack이 비워짐
Execution Context와 Block Level Scope