var x = 'xxx';
function foo () {
var y = 'yyy';
function bar () {
var z = 'zzz';
console.log(x + y + z);
}
bar();
}
foo();
처음 자바스크립트 코드를 실행하는 순간 전역 컨텍스트가 콜 스택에 담긴다.
이제 콜 스택에서 전역 컨텍스트와 관련된 코드를 순차로 진행하다가 foo함수를 호출하면 자바스크립트 엔진은 foo 실행 컨텍스트를 생성한 후 콜 스택에 담는다.
그러면 콜스택의 맨 위에 foo 실행 컨텍스트가 놓였으므로 전역 컨텍스트와 관련된 코드의 실행을 중지하고 foo 실행 컨텍스트와 관련된 코드가 실행된다.
그러다 bar함수의 실행 컨텍스트가 스택의 가장 위에 담기면 foo 실행 컨텍스트를 중지하고 bar함수 내부의 코드를 순서대로 진행한다.
bar함수의 실행이 종료되면 bar 실행 컨텍스트가 콜 스택에서 제거되고 맨 위에 있는 foo 실행 컨텍스트가 중단했던 부분부터 이어서 실행하게 된다.
우선 실행 컨텍스트 내부엔 variable environment
, lexical environment
, this binding
가 있습니다.
현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보다. 선언 시점의 LexicalEnvironment의 스냅샷으로, 변경 사항은 반영되지 않는다.
처음에는 VariableEnvironment와 같지만 변경 사항이 실시간으로 반영된다.
this 식별자가 바라봐야 할 대상 객체를 의미한다.
VariableEnvironment에 담기는 내용은 LexicalEnvironment와 같지만 최초 실행 시의 스냅샷을 유지한다는 점이 다르다. 실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LexicalEnvironment를 만들고, 이후에는 LexicalEnvironment를 주로 활용한다.
VariableEnvironment와 LexicalEnvironment의 내부는 environmentRecord와 outerEnvironmentReference로 구성되어 있다. 초기화 과정 중에는 사실상 완전히 동일하고 이후 코드 진행에 따라 서로 달라지게 된다.
이 두 환경의 내부는 다시 EnvironmentRecord 와 OuterEnvironmentReference 로 구성된다.
environmentRecord
: 함수 안의 코드가 실행되기 전에 현재 컨텍스트와 관련된 코드의 식별자 정보(매개변수의 이름, 함수 선언, 변수명 등)가 저장된다. 즉 코드가 실행되기 전에 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명 등을 모두 알고 있게 된다. (호이스팅)
outerEnvironmentReference(외부 렉시컬 환경에 대한 참조)
: 상위 스코프를 가리킨다. 즉 현재 environment record보다 바깥에 있는 environment record를 참고한다는 뜻이며 해당 실행 컨텍스트를 생성한 함수의 바깥 환경을 가리킨다. 코드 상에서 어떤 변수에 접근하려고 하면 현재 컨텍스트의 LexicalEnvironment를 탐색해서 발견되면 그 값을 반환하고, 발견하지 못할 경우 다시 outerEnvironmentRecord에 담긴 LexicalEnvironment를 탐색하는 과정을 거친다. 전역 컨텍스트의 LexicalEnvironment까지 탐색해도 해당 변수를 찾지 못하면 undefined를 반환한다.
실행 컨텍스트는 실행할 코드에 제공할 환경 정보를 모아놓은 객체입니다. 예를 들어서 어떤 실행 컨텍스트가 활성화 되는 시점에 선언된 변수들을 호이스팅하고 직전 컨텍스트 정보를 담고있는 outer공간이 있습니다. 그래서 어떤 변수에 참조하고자할 때 현재 컨텍스트를 찾고,outer에 담겨있는 직전 컨텍스트에서 찾고 이렇게 전역 컨텍스트까지 찾을 수 있게 됩니다.