식별자에 대한 유효범위
어떤 경계 A의 외부에서 선언한 변수는 A의 외부뿐 아니라 A의 내부에서도 접근이 가능하지만, A의 내부에서 선언한 변수는 A 내부에서만 접근이 가능하다.
var = 함수 스코프
let, const = 블록 스코프
var a = 1;
var outer = function () {
var inner = function () {
console.log(a);
var a = 3;
};
inner();
console.log(a);
};
outer();
console.log(a);
- 전역 컨텍스트가 활성화된다 ( javascript 실행 )
- 전역 컨텍스트의 environmentRecode에 { a, outer } 식별자를 저장한다. (전역에서 선언된 식별자)
- 전역 스코프에 있는 변수 a에 1을, outer에는 함수를 할당한다
- 10번째 줄에서 outer를 호출한다, 전역 컨텍스트가 일시 중단되고 outer 실행 컨텍스트가 활성화 되어 2번째 줄로 이동한다
- 2번째 줄 - outer 실행 컨텍스트의 environmentRecode에 { inner } 식별자를 저장한다. outerEnvironmentReference에는 outer 함수가 선언될 당시의LexicalEnvironment가 담긴다. outer는 전역에서 선언되었으니, 전역 컨텍스트의 ExicalEnvironment를 참조복사한다. 이를 [ GLOBAL, { a, outer }]라고 표기한다. 첫번째는 실행 컨텍스트의 이름, 두번째는 environmentRecode 객체다.
- 3번째 줄 - outer 스코프에 있는 변수 inner에 함수를 할당한다.
- 7번째 줄 - inner 함수를 호출한다. 이에 따라 outer 실행 컨텍스트의 코드는 7번째 줄에서 임시중단되고, 실행 컨텍스트가 활성화되어 3번째 줄로 이동한다.
- 3번째 줄 - inner 실행 컨텍스트의 environmentRecode에 { a } 식별자를 저장합니다. outerEnvironmentReference에는 inner 함수가 선언될 당시의 LexicalEnvironment, 즉 [ outer, { inner }]를 참조복사한다.
- 4번째 줄 - 식별자 a에 접근하고자 한다. 현재 활성화 상태인 inner 컨텍스트의 environmentRecode에서 a를 검색한다. a가 발견되었는데 여기에는 아직 할당된 값이 없다 (undefined)
- 5번째 줄 - inner 스코프에 있는 변수 a에 3을 할당한다.
- 6번째 줄 - inner 함수 실행이 종료된다. inner 실행 컨텍스트가 콜 스택에서 제거되고 바로 아래의 outer 실행 컨텍스트가 다시 활성화되면서 앞서 중단했던 7번째 줄의 다음으로 이동한다.
- 8번째 줄 - 식별자 a에 접근한다. 이때 자바스크립트 엔진은 활성화 된 실행 컨텍스트의 LexicalEnvironment에 접근한다. 첫 요소의 environmentRecord에서 a가 있는지 찾아보고 없으면 outerEnvironmentReference에 있는 environmentRecord로 넘어가는 식으로 계속해서 검색한다. 예제는 두번째, 즉 전역 LexicalEnvironment에 a가 있으니 그 a에 저장된 값 1을 반환
- 9번째 줄 - outer 함수 실행이 종료된다. outer 실행 컨텍스트가 콜스택에서 종료되고 , 바로 밑의 전역 컨텍스트가 다시 활성화되면서, 앞서 중단한 10번째 줄의 다음으로 이동한다
- 11번째 줄 - 식별자 a에 접근하고자 합니다. 현재 활성화 상태인 전역 컨텍스트의 environmentRecord에서 a를 검색한다. 바로 a를 찾을 수 있었다.