변수는 어떠한 순서로 해결될까? - 스코프 체인 -

JavaScript에서는 스크립트의 실행 시에 내부적으로 Global 객체(글로벌 객체)를 생성한다고 했다. 글로벌 객체는 기본적으로 프로그래머가 의식할 필요가 없는 [글로벌 변수나 글로벌 함수를 관리하기 위한 편의적인 객체]다. 글로벌 변수나 글로벌 함수는 [글로벌 객체의 프로퍼티나 메소드다]라고 바꾸어 말할 수도 있다.

[그렇다면 로컬 변수도 실은 객체의 프로퍼티가 아닌가?]라고 혹시 눈빛을 반작이는 사람이 있을지도 모르겠다. 그렇다! 간파한 그대로다. 실은 로컬 변수는 Activation 객체(보통은 Call 객체라고도 한다)의 프로퍼티다.

Call 객체는 [함수 호출이 있을 때마다 내부적으로 자동 생성되는 객체]다. 글로벌 객체와 같이 [함수 내에서 정의된 로컬 변수를 관리하기 위한 편의적인 객체]로, 실은 방금 전에 등장한 arguments 프로퍼티도 Call 객체의 프로퍼티다.

자, 글로벌 객체와 더불어서 Call 객체, 즉 이렇게 [프로그래머가 스스로 생성하는 것도 아니고, 게다가 프로그램으로부터 명시적으로 호출될 수도 없어 통상적으로 프로그래머가 의식조차 하지 않아도 될 것들을 왜 이해해두어야 하는가?]라고 의문을 가질 수도 있을 것이다. 그 이유는 이러한 것들의 존재를 이해해둠으로써 변수를 해결하는 메커니즘을 이해할 수 있기 때문이다.

그 메커니즘이 바로 스코프 체인이다. 스코프 체인이란 글로벌 객체, Call 객체를 생성 순서대로 연결할 리스트를 말한다.
JavaScript에서는 각각의 스코프 단위로 글로벌 객체, Call 객체가 생성된다. 이것들을 생성 순서대로 연결한 것이 스코프 체인이다.

JavaScript에서는 이 스코프 체인의 선두에 위치하는 객체로부터 순서대로 프로퍼티(변수)를 검색해, 매치하는 프로퍼티가 [처음] 발결된 곳에서 그 값을 채택하고 있다.

예를 들어, 아래와 같은 Inner 함수의 예를 보자.


							var y = 'Global';
							
							function outerFunc () {
								var y = 'Local Outer';
								
								function innerFunc () {
									var z = 'Local Inner';
									$.print(z);
									$.print(y);
									$.print(x); // Uncaught ReferenceError: x is not defined 
								}

								innerFunc();
							}

							outerFunc();
						

이 코드에서는 아래와 같은 스코프 체인 - 선두로부터 내부의 Call 객체, 외부의 Call 객체, 글로벌 객체 - 이 완성되어 있을 것이다. 이러한 스코프 체인으로 각각 변수 x, y, z를 참조하려고 했을 경우, 아래의 그림과 같은 순서로 변수가 해결되게 된다.

스코프 체인을 이해함으로써 변수명이 중복되었을 경우에 변수의 해결에 대한 명확한 규칙을 알게 될 것이다.