실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
실행할 코드는 뭐고, 제공할 환경 정보들은 뭐지?
//전역 컨텍스트 -(1)
var a = 1;
function outer() {
//outer 컨텍스트
function inner() {
//inner 컨텍스트
console.log(a)
var a = 3
}
inner() -(3)
console.log(a)
}
outer() -(2)
console.log(a)
자바스크립트는 파일이 열리는 순간 맨 처음 전역 컨텍스트가 활성화되고,
위에서 아래로 코드를 읽어나가면서 함수를 호출하면 호출한 위치에서 해당 컨텍스트를 비활성화시키고 호출한 함수의 컨텍스트를 활성화한다.
그 과정에서 콜스택에는 위 그림과 같은 순서로 컨텍스트가 쌓이게 된다.
반대로 맨 위에 있는 inner 함수 코드가 끝나면 inner 컨텍스트가 콜 스택에서 제거되고, 이 과정을 반복하면서 결국 콜 스택은 비워지게 된다.
알겠고, 실행 컨텍스트에는 뭐가 있는건데?
어떤 실행 컨텍스트가 활성화될 때 자바스크립트 엔진은 해당 컨텍스트에 관련된 코드를 실행하는데 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장한다.
그 정보는 크게 세 가지로 나뉜다.
여기서 VariableEnvironment는 LexicalEnvironment의 초기 정보, 즉 실행 컨텍스트를 생성할 때 담긴 정보이다.
반대로 말하면 LexicalEnvironment는 코드 진행에 따라 달라지는 정보를 갱신시키고, VariableEnvironment는 초기 정보를 그대로 간직한다.

environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보가 저장된다.
식별자의 예로는 함수의 매개변수, 변수 식별자, 함수 자체 등이 있겠다.
위 과정은 코드가 실행되기 전에 진행되며, 변수에 할당된 데이터는 읽지 않기 때문에 정말 그 식별자만을 저장한다.
이 부분을 호이스팅이라고도 한다. 호이스팅은 변수나 함수가 끌어 올려지는 것처럼 보이는 것이다.
이후 해당 컨텍스트의 코드를 읽어나가며 LexicalEnvironment의 environmentRecord를 수정해나간다.
outerEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.
outerEnvironmentReference는 현재 실행 컨텍스트의 호출된 함수가 선언된 시점부터 전역 컨텍스트의 LexicalEnvironment까지 체인 형태로 이어진다 : 스코프 체인
이게 언제 쓰이냐?! 하면..
현재 실행 컨텍스트에서 특정 식별자에 접근하려 할 때, 현재 실행 컨텍스트의 LexicalEnvironment에 해당 식별자가 없다면 outerEnvironmentReference를 참조하고, 또 없으면 스코프 체인을 따라 전역 컨텍스트의 LexicalEnvironment까지 찾는다. 만약 끝까지 가도 해당 식별자가 없으면 undefined를 리턴한다.
this는 상황에 따라서 값이 바뀌는 아주 복잡한 녀석이다. 다음 포스팅은 this를 다루겠다!