실행 컨텍스트와 스코프
실행 컨텍스트란?
ECMAScript의 정의를 살펴보면 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이라고 설명하고 있다.
즉 실행 가능한 자바스크립트 코드 블록이 실행되는 환경이라고 할 수 있다. 실행 가능한 코드에는 전역 코드, eval() 코드, 함수 코드가 있다.
우리는 오늘 한가지 예제를 통해 콜 스택부터 실행 컨텍스트, 스코프가 어떻게 설계되는 지에 대해 살펴보도록 하겠다.
참조사이트var x = 'xxx';
function foo () {
var y = 'yyy';
function bar () {
var z = 'zzz';
console.log(x + y + z);
}
bar();
}
foo();
이 코드에서는 스택이 쌓이고 소멸하게 된다.
- 실행 가능한 코드가 새로운 실행 컨텍스트 스택으로 생성된다. 이때는 후입선출(LIFO)로 진행된다.
- 전역 실행 컨텍스트는 처음에 만들어져 컨텍스트가 끝날 때까지 유지된다
- 함수 호출 시 스택이 쌓인다.
- 함수 호출이 끝나면 실행 컨텍스트를 파기하고 직전 실행 컨텍스트의 컨트롤을 반환한다.
실행 컨텍스트 생성과정
- 전역 컨텍스트의 경우
전역에 선언된 전역변수와 전역 함수를 객체로 갖는다.
- 함수 컨텍스트의 경우
활성 객체를 가리키며 매개변수와 인수들의 정보를 가지고 있는 arguments객체가 추가된다.
순서로는 우선 활성 객체를 생성한다. 그 후 arguments 객체를 생성한다. 이 떄 활성객체는 arguments 프로퍼티로 arguments 객체를 참조하게 된다. 그 후 스코프의 정보를 생성한다. 연결 리스트와 유사한 형태로 만들어지며 [[scope]] 프로퍼티로 참조된다. 그 후 변수를 생성한다. 주의할 점은 생성과 초기화만 진행할 뿐, 실행되기 전까지는 할당이 이루어지지 않는다는 것이다. 마지막으로 this를 할당하는 데 함수 호출 패턴에 따라 this가 참조하는 객체가 정해진다.
- 전역 코드 진입
전역 객체가 생성되면 전역 코드로 컨트롤이 진입하여 전역 실행 컨텍스트가 생성되고 실행 컨텍스트가 쌓인다.
- 스코프 체인 생성 및 초기화
이 때 스코프체인은 전역 객체 레퍼런스를 포함한다.
- 변수 객체화
여기선 매개변수가 변수 객체의 프로퍼티로 인수가 값으로 설정된다. 그 후 코드 내 함수 선을 대상으로 변수 객체가 프로퍼티로, 생성된 함수 객체가 값으로 설정되며 함수 호이스팅이 발생한다. 그 다음 대상 코드 대상으로 변수 명이 변수 객체의 프로퍼티로 undefined가 값으로 설정된다. 이를 변수 호이스팅이라고 한다.
이후 위 코드의 함수 foo가 처리된다. 함수 foo가 프로퍼티로 생성된 함수 객체가 값으로 지정된다. 이 때 생성된 함수 객체는 [[scope]] 프로퍼티를 가진다. 이 때 [[scope]] 프로퍼티는 자신의 실행환경을 가지고 자신을 포함하는 외부 함수와 실행 환과 전역 객체를 가리킨다. 또한 자신을 포함하는 외부 함수의 실행 컨텍스트가 소멸하여도 [[scope]] 프로퍼티가 가리키는 외부함수 실행환경을 참조할 수 있는데 이것이 클로저다.
이후 변수 x를 처리하는데 var 변수는 선언과 초기화가 한 번에 이루어진다. 그 후 this value를 정한다. 이전에는 this가 전역 객체를 가리키다가, 함수 호출 패턴에 이해 this가 정해진다.