실행 컨텍스트란 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
스코프란 식별자에 대한 유표범위이다.
ES5까지의 자바스크립트에서 스코프는 오직 함수에 의해서만 생성된다.
스코프 체인이란 '식별자의 유효범위'를 안에서부터 바깥으로 차례로 검색해나가는 것을 말한다.
이를 가능케 하는 것이 LexicalEnvironment 내부의 outerEnvironmentReference이다.
outerEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.
각 outerEnvironmentReference는 오직 자신이 선언된 시점의 LexicalEnvironment만 참조한다.
01 var a = 1;
02 var outer = function () {
03 var inner = function () {
04 console.log(a);
05 var a = 3;
06 };
07 inner();
08 console.log(a);
09 };
10 outer();
11 console.log(a);
1. 자바스크립트 파일이 열리는 순간 전역 컨텍스트가 활성화된다.
전역 컨텍스트의 environmentRecord에 { a, outer } 식별자를 저장한다.
선언 시점이 없음으로 전역 컨텍스트의 outerEnvironmentReference에는 아무것도 담기지 않는다.
2. 변수 a에 1을, outer에 함수를 할당한다.
3. 10번째 줄의 outer 함수를 호출한다.
전역 컨텍스트의 코드는 임시중단 되고, outer 실행 컨텍스트가 활성화되어 2번째 줄로 이동한다.
4. outer 실행 컨텍스트의 environmentRecord에 { inner } 식별자를 저장한다.
outerEnvironmentReference에는 전역 컨텍스트의 LexicalEnvironment인
[ GLOBAL, { a, outer } ]이 담긴다. GLOBAL은 실행 컨텍스트의 이름이다.
5. 변수 inner에 함수를 할당한다.
6. 7번째 줄의 inner 함수를 호출한다.
outer 실행 컨텍스트의 코드는 임시중단되고, inner 실행 컨텍스트가 활성화되어 3번째 줄로 이동한다.
7. inner 실행 컨텍스트의 environmentRecord에 { a } 식별자를 저장한다.
outerEnvironmentReference에는 outer 함수의 LexicalEnvironment인
[ outer, { inner } ]이 담긴다.
8. 4번째 줄의 a에는 아직 할당된 값이 없음으로 undefined를 출력한다.
5번째 줄에 있는 변수 a에 3을 할당한다.
9. inner 함수가 종료되고, inner 실행 컨텍스트가 콜 스택에서 제거된다.
outer 실행 컨텍스트가 다시 활성화되면서 8번째 줄로 이동한다.
10. 8번째 줄의 a에 접근하기 위해 자바스크립트 엔진은
활성화된 실행 컨텍스트의 LexicalEnvironment에 접근한다.
outer 실행 컨텍스트의 environentRecord에는 a 식별자가 없음으로,
한 단계 올라가 전역 컨텍스트의 environmentRecord에 있는 a에 저장된 값 1을 반환한다.
11. outer 함수가 종료되고, outer 실행 컨텍스트가 콜 스택에서 제거된다.
전역 컨텍스트가 다시 활성화되면서 11번째 줄로 이동한다.
12. 현재 활성화 상태인 전역 컨텍스트의 environentRecord에서 a를 검색하고 1을 반환한다.
13. 전역 컨텍스트가 콜 스택에서 제거되고 종료된다.
위의 예시에서 변수 a는 inner 함수 내부에서 선언되어 있다.
따라서 전역 공간에서 선언한 동일한 이름의 변수 a에는 접근할 수 없으며, 이를 '변수 은닉화'라고 한다.
코어 자바스크립트(Core JavaScript)
https://book.naver.com/bookdb/book_detail.nhn?bid=15433261