
👉 ‘코어 자바스크립트’의 ‘02 실행 컨텍스트’를 읽으며 기억할 내용들과 새로 알게 된 내용을 정리하였습니다.
var eternalLoop = function() {
return eternalLoop();
}
// Uncaught RangeError; Maximum call stack size exceeded 실행 컨텍스트와 콜 스택 예시:// ------------------------------ (1)
var a = 1;
function outer() {
function inner() {
console.log(a); // undefined
var a = 3;
}
inner(); // ------------------- (2)
console.log(a); // 1
}
outer(); // -------------------- (3)
console.log(a); // 1 위 코드에 대한 설명.(1) 자바스크립트 코드를 실행하는 순간 전역 컨텍스트가 콜 스택에 push.
(3) outer 함수를 호출하면 자바스크립트 엔진은 outer에 대한 환경 정보를 수집해서 outer 실행 컨텍스트를 생성한 후 콜 스택에 push. (콜 스택 맨 위에 outer 실행 컨텍스트가 놓인 상태가 됐으므로, 전역 컨텍스트와 관련된 코드의 실행을 일시 중단하고 대신 outer 실행 컨텍스트와 관련된 코드, 즉 outer 함수 내부의 코드들을 순차적으로 실행)
(2) inner 함수의 실행 컨텍스트가 콜 스택의 가장 위에 담기면 outer 컨텍스트와 관련된 코드의 실행을 중단하고 inner 함수 내부의 코드를 순서대로 진행.
inner 함수 실행 종료되면 콜 스택에서 제거.
아래에 있던 outer 컨텍스트가 콜 스택 맨 위에 존재하게 되므로, (2)의 다음줄부터 이어서 실행.
a 변수 출력하면 outer 실행 컨텍스트가 콜 스택에서 제거되고, 전역 컨텍스트만 존재.
실행을 중단했던 (3) 다음줄 이어서 실행.
a 변수 값 출력하면 전역 공간에 실행할 코드가 없어 전역 컨텍스트도 제거. 콜 스택 비어진 채로 종료.

실행 컨텍스트가 활성화 될 때 자바스크립트 엔진은 해당 컨텍스트에 관련된 코드들을 실행하는데 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장.
VariableEnvironment: 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보. 선언시점의 스냅샷으로 변경사항 미반영.LexicalEnvironment: 처음에는 VariableEnvironment와 같지만, 변경사항이 실시간으로 반영.ThisBinding: this 식별자가 바라봐야 할 대상 객체.VariableEnvironment에 담기는 내용은 LexicalEnvironment와 같지만, 최초 실행 시의 스냅샷을 유지한다는 점이 다르다.VariableEnvironment에 정보를 먼저 담고, 이를 그대로 복사해서 LexicalEnvironment를 만들고, 이후에는 LexicalEnvironment를 주로 활용한다.environmentRecord와 outerEnvironmentReference로 구성되어있다.2-3-1 environmentRecord와 호이스팅
environmentRecord: 현재 컨텍스트와 관련된 코드의 식별자 정보 저장.
호이스팅(hoisting): 매개변수 식별자,함수 선언문, 변수 식별자 등 컨텍스트 내부 전체를 처음부터 스캔하며, 수집.function a (x) { // 수집 대상 1(매개변수)
console.log(x); // (1)
var x; // 수집 대상 2(변수 선언)
console.log(x); // (2)
var x = 2; // 수집 대상 3(변수 선언)
console.log(x); // (3)
}
a(1);
호이스팅이 되지 않을 때 예상 값: (1) - 1, (2) - undefined, (3) - 2
실제: (1) - 1, (2) - 1, (3) - 2
function a () {
console.log(b); // (1)
var b = 'bbb'; // 수집 대상 1(변수 선언)
console.log(b); // (2)
function b () { } // 수집 대상 2(함수 선언)
console.log(b); // (3)
}
a();
호이스팅이 되지 않을 때 예상 값: (1) - undefined, (2) - ‘bbb’, (3) - function b
실제: (1) - function b, (2) - ‘bbb’, (3) - ‘bbb’
함수 선언문, 함수 표현식
function a () { } // 함수 선언문. 함수명 a가 곧 변수명.
a(); // 실행 OK.
var b = function () { } // 익명 함수 표현식. 변수명 b가 곧 함수명.
b(); // 실행 OK.
var c = function d () { } // 기명 함수 표현식. 변수명은 c, 함수명은 d.
c(); // 실행 OK.
d(); // 에러!
할당한 것.2-3-2 스코프, 스코프 체인, outerEnvironmentReference
스코프(scope): 식별자에 대한 유효범위.
스코프 체인(scope chain)
: 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것.
outerEnvironmentReference
: 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조.
LexicalEnvironment를 참조하고, 함수 B의 outerEnvironmentReference가 함수 A의 LexicalEnvironment를 참조.linked list 형태무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에만 접근 가능변수 은닉화(variable shadowing): 함수에서 선언한 변수는 외부의 동일한 이름의 변수에 접근할 수 없다.💡 크롬 브라우저 환경에서 스코프 체인 중 현재 실행 컨텍스트를 제외한 상위 스코프 정보를 개발자 도구의 콘솔로 확인 가능.
console.dir(함수명);⇒ 함수 내부에서 실제로 호출할 외부 변수들의 정보만 노출. ⇒ 브라우저 성능 향상 목적.
전역변수, 지역변수
전역변수(global variable): 전역 공간에서 선언한 변수.지역변수(local variable): 함수 내부에서 선언한 변수는 무조건 지역변수.실행 컨텍스트의 ThisBinding에는 this로 지정된 객체가 저장. 실행 컨텍스트 활성화 당시에 this가 지정되지 않은 경우 this에는 전역 객체가 저장. 함수를 호출하는 방법에 따라 this에 저장되는 대상이 다르다.
✅실행 컨텍스트 객체는 활성화되는 시점에 VariableEnvironment, LexicalEnvironment, ThisBinding의 3가지 정보 수집.
✅ 생성 시에는 VariableEnvironment와 LexicalEnvironment가 동일하지만, LexicalEnvironment는 함수 실행 도중에 변경되는 사항이 즉시 반영되나, VariableEnvironment는 초기 상태 유지.
✅ LexicalEnvironment는 매개변수명, 변수 식별자, 선언한 함수명 등을 수집하는 environmentRecord와 바로 직전 컨텍스트의 LexicalEnvironment 정보를 참조하는 outerEnvironmentRecord로 구성.