실행 컨텍스트는 자바스크립트의 동작 원리의 근간이며 핵심 개념이다. 실행 컨텍스트를 정확히 이해하면 호이스팅, 클로저, 이벤트 핸들러, 비동기 처리 등 자바스크립트의 어렵게 느껴지는 개념들을 정확히 이해할 수 있게 된다.
ECMAScript는 소스코드를 4가지 타입으로 구분한다.
자주 사용하지 않는 eval코드를 제외한 소스코드는 종류에 따라 각각 실행 컨텍스트를 생성하게 된다.
코드가 실행되면 스코프, 식별자, 코드 실행 순서 등의 관리가 필요하다.
이러한 동작들을 관리하는 것이 실행 컨텍스트이다. 실행 컨텍스트는 소스코드의 실행에 필요한 환경을 제공하고, 실행 결과를 실제로 관리하는 영역이다.
실행 컨텍스트는 식별자를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 메커니즘으로, 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다. 먼저 실행 컨텍스트 스택에 대해 알아보자
const a = 1;
function func1() {
const b = 2;
function func2() {
const c = 3;
console.log("hello");
}
func2();
}
func1();
위 코드는 위에서 살펴본 것 처럼 전역 코드와 함수 코드로 이루어져 있다.
자바스크립트 엔진은 먼저 전역 코드를 평가하여 전역 실행 컨텍스트를 생성하고 함수가 호출되면 함수 코드를 평가하여 함수 실행 컨텍스트를 생성한다.
이 때 실행 컨텍스트는 실행 컨텍스트 스택이라는 자료구조에 의해 관리된다.
위 그림과 같이 실행 컨텍스트 스택은 코드의 실행 순서를 관리한다.
실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트는 언제나 실행 중인 코드의 실행 컨텍스트다. 이를 running execution context(실행 중인 컨텍스트)라고 한다.
렉시컬 환경은 식별자와 바인딩된 값, 그리고 상위 스코프에 대한 참조 등을 관리하는 자료구조로 실행 컨텍스트의 요소이다. 실행 컨텍스트 스택이 코드의 실행 순서를 관리하는 것처럼, 렉시컬 환경은 스코프와 식별자를 관리한다.
렉시컬 환경은 key-value형태의 스코프를 생성하여 식별자를 key로 등록하고 바인딩된 값을 관리한다.
즉 렉시컬 환경이란 스코프를 구분하여 식별자를 등록하고 관리하는 저장소 역할을 하는 렉시컬 스코프의 실체이다.
실행 컨텍스트는 렉시컬 환경(LexicalEnvironment)와 VariableEnvironment로 구성된다.
생성 초기에 이들은 같은 렉시컬 환경을 참조하며 이후 몇 가지 상황을 만나면(ex. let, const변수 등) VariableEnvironment를 위한 새로운 렉시컬 환경을 생성한다.
렉시컬 환경은 크게 Environment Record와 외부 렉시컬 환경을 참조하는 Outer Lexical Environment로 구성된다.
자바스크립트는 위와 같은 실행 컨텍스트를 기반으로 스코프, 실행 순서 등을 관리한다. 다음 포스팅에선 이러한 자료구조로 어떻게 코드가 관리되는지 예제를 통해 살펴보겠다.