실행컨텍스트 란?
실행컨텍스트는 코드가 실행되기 위한 필요한 환경들을 모아둔 것입니다. 자바스크립트 엔진에는 코드 실행을 관할하는 call stack이 있습니다. 콜스택은 실행컨텍스트를 1개씩 쌓아두고 실행하게 됩니다. 이 때 콜스택의 순서는 보장하고 순서는 FILO (First In, Last Out) 가 됩니다. (처음 들어온 것이 맨 나중에 나옵니다.)
실행컨텍스트의 실제 예시
const temp = 'temp';
function b (){
console.log('안녕하세용');
}
function a (){
b();
}
a();
- 처음 실행될 때 global인 전역 컨텍스트가 쌓입니다.
- a가 실행되었고 a 컨텍스트가 쌓입니다.
- a 내부에는 b가 실행되었고 b 컨텍스트가 쌓입니다.
- b 컨텍스트에는 콘솔을 찍는 코드가 있고 콘솔에 찍히면서 b 컨텍스트는 제거가 됩니다.
- a 컨텍스트가 실행이 되고 b 함수가 실행되었기에 a 컨텍스트는 제거가 됩니다.
- 더 이상 콜스택이 없으므로 전역 컨텍스트가 제거되고 코드 실행이 종료됩니다.

컨텍스트의 내부
컨텍스트 내부에는 variable environment, lexical environment, this binding 가 있습니다.
variable environment
생성될 때 초기 환경을 기억합니다.
variable environment에는 environmentRecord과 outerEnvironmentReference가 있습니다.
lexical environment
변경되는 실시간 환경들을 기억합니다.
lexical environment에는 environmentRecord과 outerEnvironmentReference가 있습니다.
environmentRecord
현재 컨텍스트 내부의 식별자 정보가 들어있습니다.
outerEnvironmentReference
외부 환경 정보에 접근 할 수 있습니다. 이를 통해 선언된 외부 lexical environment에 접근할 수 있습니다.
this binding
this의 정보가 담겨져 있습니다.
this는 함수가 호출될 때 this가 결정됩니다.
- 일반 함수 호출
- 메소드 호출
- 생성자 함수 호출
- apply/call/bind로 의도적인 this 바인딩
- 1번은 전역객체를 가리키게 됩니다.
- 2번과 3번은 해당 객체 또는 인스턴스가 this가 됩니다.
- 4번을 통해 개발자가 의도적으로 this를 결정시킬 수도 있습니다.
예시
var a = 1;
function outer () {
function inner () {
console.log(a);
var a = 3;
console.log(a);
}
inner();
console.log(a);
}
outer();
console.log(a);
- 전역 컨텍스트가 쌓이고 a 변수가 environmentRecord에 쌓입니다.
- outer가 실행되고 컨텍스트에 쌓입니다.
- outer 함수 내부에는 inner가 있고 inner가 실행되어 컨텍스트에 쌓입니다.
- inner 내부가 실행이 됩니다.
- inner 내부에는 a가 정의되어 있고 environmentRecord에서 변수, 함수 등의 정보를 미리 수집하기 때문에 a가 undefined로 호이스팅이 됩니다. (할당은 호이스팅이 되지 않습니다.)
- a가 할당되기 전 콘솔을 찍는 코드가 나왔고 5의 설명대로 undefined가 찍힙니다.
- a는 3으로 할당되고 그 이후에 콘솔 코드는 3을 찍게됩니다.
- inner가 모두 실행되어 inner 컨텍스트가 삭제 됩니다.
- outer 함수에 콘솔 a를 찍는 코드가 있습니다. outer에는 변수 a에 대한 정보가 없습니다.
- outerEnvironmentReference를 통해 전역 컨텍스트에 접근하고 전역에는 1이라는 정보가 있습니다.
- 1이 찍히게 됩니다.
- outer 함수가 모두 실행되어 실행컨텍스트에 제거가 됩니다.
- 전역에 a를 콘솔에 출력하라는 코드가 있습니다. 전역컨텍스트에 1의 정보가 있기에 1을 출력합니다.
- 전역 컨텍스트도 제거가 되며 모든 코드의 해석이 끝나게 됩니다.
if) 만약에 var가 아닌 let으로 선언되었다면?
TDZ의 영향으로 레퍼런스 에러를 일으키게 됩니다.
참고
실행 컨텍스트
실행 컨텍스트 참고 코드
this