[JS] 실행 컨텍스트
실행 컨텍스트란?
실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체다.
각 실행 컨텍스트는 해당 코드 블록이 실행되는 동안 필요한 모든 정보를 담고 있다. 이 정보에는 변수, 함수, 객체 등의 정보를 담고 있으며 코드의 실행이 이루어질 때 해당 컨텍스트에 따라 변수의 범위 및 값이 결정된다.
실행 컨텍스트 동작 과정
동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고 콜 스택에 쌓아 올린다.
가장 위에 쌓여있는 실행 컨텍스트와 관련 있는 코드들을 실행하여 전체 코드의 환경과 순서를 보장한다.
var a = 1;
function outer() {
function inner() {
console.log(a); // undefined
var a = 3;
}
inner();
console.log(a); // 1
}
outer();
console.log(a); // 1
위 코드의 순서를 실행 컨텍스트 관점에서 보면 아래와 같이 나타낼 수 있다.
- 전역 컨텍스트를 콜 스택에 추가한다.
- 전역 컨텍스트와 관련된 코드들을 순차로 진행한다.
- outer에 대한 환경 정보 수집한다.
- outer 실행 컨텍스트 생성 후 콜 스택에 추가한다.
- 전역 컨텍스트와 관련된 코드의 실행 일시 중단한다. (콜 스택 맨 위에 outer 실행 컨텍스트가 놓인 상태)
- outer 함수 내부의 코드 순차로 실행한다.
- inner 실행 컨텍스트 생성 후 콜 스택에 추가한다.
- outer와 관련된 코드의 실행 일시 중단한다. (콜 스택 맨 위에 inner 실행 컨텍스트가 놓인 상태)
- inner 함수 내부의 코드 순차로 실행한다.
- 이후에 함수 실행이 종료되면 inner 실행 컨텍스트는 콜 스택에서 제거된다.
- 일시 중단했던 outer와 관련된 코드를 다시 실행하고 실행이 종료되면 콜 스택에서 제거된다.
- 일시 중단했던 전역 컨텍스트와 관련된 코드를 다시 실행하고 실행이 종료되면 콜 스택에서 제거된다.
실행 컨텍스트 구성
Variable Environment
선언된 변수들을 포함한 환경을 나타내는 객체로, 자신의 외부 환경에 대한 참조를 가지고 있으면 호이스팅된 변수들의 정보가 포함된다.
Variable Environment에 담기는 내용은 Lexical Environment와 같지만 최초 실행 시의 스냅샷을 유지하며 변경 사항을 반영하지 않는다.
실행 컨텍스트를 생성할 때 Variable Environment에 정보를 먼저 담은 다음 이를 복사해서 Lexical Environment를 만든다.
Lexical Environment
변수, 함수 등의 정보를 담은 환경을 나타내는 객체로, 자신의 외부 환경에 대한 참조를 가지고 있다.
Lexical Environment 는 초기에는 Variable Environment 와 같지만 변경 사항을 실시간으로 반영한다.
Lexical Environment의 내부에는 Environment Record와 Outer Environment Reference로 구성되어 있다.
Environment Record (환경 레코드)
Environment Record는 JS 엔진이 처음에 전체 코드를 스캔하면서 변수와 같은 정보를 미리 기록해 놓는 곳이다. 환경 레코드에는 변수, 매개변수, 함수 등의 정보가 담겨 있다. 이 정보를 바탕으로 코드 실행 중에 필요한 데이터를 추적하고 관리하게 도와준다.
Outer Environment Reference (외부 환경 참조)
Outer Environment Reference는 현재 실행 컨텍스트의 바로 바깥쪽에 있는 실행 컨텍스트를 가리킨다. 즉, 현재 실행 중인 함수가 어디서 호출되었는지를 나타낸다.
This Binding
this 키워드가 바인딩되는 객체로, 호출 방식에 따라 결정된다.
실행 컨텍스트 활성화 당시에 this가 지정되지 않은 경우 this에는 전역 객체가 저장된다.