자바스크립트 엔진이 코드를 실행하기 위해서는 코드에 대한 정보들이 필요하다.
코드에 선언된 변수와 함수, 스코프, this, arguments 등을 묶어, 코드가 실행되는 위치를 설명한다는 뜻의 Execution Context라고 부른다.
자바스크립트 엔진은 Execution Context를 객체로 관리하며 코드를 Execution Context내에서 실행한다.
코드를 실행하며 단 한 개만 정의되는 전역 Context
global object를 생성하며 this 값에 global object를 참조한다.
전역 실행 컨텍스트는 Call Stack에 가장 먼저 추가되며 앱이 종료 될 때 삭제된다.
함수가 실행 될 때마다 정의되는 Context
매 실행시마다 정의되며 함수 실행이 종료(return)되면 Call Stack에서 제거된다.
eval 함수로 실행한 코드의 Context
보안상 취약한 점이 있어 비권장 함수이다.
js엔진은 생성된 Context를 관리하는 목적의 Call Stack을 갖고 있다.
js는 단일 스레드 형식이기 때문에 런타임에 단 하나의 Call Stack이 존재한다.
Call Stack은 최대 stack 사이즈가 정해져 있다. Call Stack에 쌓인 Context Stack이 최대치를 넘게 될 경우 'RangeError: Maximum call stack size exceeded’라는 에러 발생 = Stack Overflow
LexicalEnvironment와 VariableEnvironment의 두 가지 구성으로 이루어지며, Environment들은 생성 시 같은 속성 카테고리를 가지고 있다.
ExecutionContext :{
LexicalEnvironment:{
Environment Records,
Reference to the outer environment,
},
VariableEnvironment:{
Environment Records,
Reference to the outer environment,
}
}
외부 환경 참조는 정적 스코프를 기준으로 상위 scope의 Lexical Environment를 참조한다.
즉, 가장 먼저 생성 되는 Global Execution Context는 외부 환경 참조 값으로 null를 갖는다. 그리고 Functional Execution Context는 상위 Scope에 해당하는 Lexical Environment를 외부 환경 참조 값으로 갖는다. 이 연결 고리는 변수 탐색 시 사용된다.
일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례대로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결되고 있는지 보여주는 것
즉, 자기 자신의 스코프를 제외한 자신과 가장 가까운 변수 객체의 모든 스코프들
let name = "Jason";
function fn1() {
console.log(name); //Jason
}
function fn2() {
let name = "Peter";
console.log(name); // Peter
fn1();
}
fn2();
Lexical Environment 내에 식별자 바인딩을 기록하는 객체이며 Environment Record를 상속하는 세개의 서브 클래스로 구성되어 있다.
Environment Record:{
Declarative Environment Record,
Object Environment Record,
Global Environment Record
}
Declarative Environment Record
함수와 변수, this, super 등의 식별자 바인딩이 저장 되며, Variable Environment와 Lexical Environment는 각각 다른 방식으로 선언된 변수들을 관리한다.
Variable Environment는 Lexical Environment를 상속하는 관계
그래서 Lexical Environment와 Variable Environment 모두 Lexical Environment라고 말할 수 있다.
Lexical Environment는 let과 const로 선언된 변수들을 위한 local lexical scope를 단위로 한다.
Variable Environment는 var로 선언된 변수들을 위한 functional scope를 단위로 한다.
Execution Context는 Creation과 Execution의 두 단계를 거쳐 생성된다.
1. Creation Phase
Creation 단계에선 Lexical Environment와 Variable Environment의 정의가 이루어진다.
This binding과 Outer Reference를 결정하고, Environment Record에 변수 식별자에 대한 메모리가 매핑되며 값의 할당은 선언 방식에 따라 다르게 이루어진다.
2. Execution Phase
Creation 단계에서 코드 실행을 위한 환경 정보 값이 결정되었다면, Execution은 코드를 위에서 부터 읽으며 실행한다. 변수 값이 할당되는 코드가 실행 될 경우 Environment Record에 저장된 식별자 메모리에 값을 수정 또는 할당한다.
➡ js엔진이 코드를 실행(Execution Phase)하기 전 코드의 실행 환경 정보를 구축(Creation Phase)하는 것이 hoistind이 이루어지는 이유