실행 컨텍스트란 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
스택(Stack)은 출입구가 하나인 LIFO(Last In First Out) 구조이다.
스택에 a, b, c, d를 순서대로 저장하면 꺼낼 때 d, c, b, a 순서대로 나온다.
큐(Queue)는 양쪽이 모두 열려있는 FIFO(First In First Out) 구조이다.
큐에 a, b, c, d 를 순서대로 저장하면 꺼낼 때 a, b, c, d 순서대로 나온다.
동일한 환경에 있는 코드를 실행할 때 필요한 환경 정보들들 모아 컨텍스트를 구성한다. 이를 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는 코드들을 실행한다.
실행 컨텍스트를 구성할 수 있는 방법은 전역, eval() 함수, 함수 실행이 있다.
// ------------------------------- (1)
var a = 1;
function outer() {
function inner() {
console.log(a); // undefined ----- (a)
var a = 3;
}
inner(); // ------------------ (2)
console.log(a); // 1 ----- (b)
}
outer(); // ---------------------- (3)
console.log(a); // 1 ----- (c)
즉, 어떤 실행 컨텍스트가 콜 스택의 맨 위에 쌓이는 순간이 곧 현재 실행할 코드에 관여하게 되는 시점이다.
실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체라고 했다.
여기에 담기는 정보에는 VariableEnvironment
, LexicalEnvironment
, ThisBinding
이 있다.
VariableEnvironment
는 현재 컨텍스트 내의 식별자들에 대한 정보와 외부 환경 변수를 말한다.
최초 실행 시의 스냅샷을 유지하며, 변경 사항은 반영되지 않는다.
LexicalEnvironment
는 변경 사항이 실시간으로 반영된다.
LexicalEnvironment 내부는 environmentRecord
와 outer-EnvironmentReference
로 구성되어 있다.
environmentRecord
에는 현재 컨텍스트와 관련된 코드들의 식별자 정보들이 저장된다.
변수 정보를 수집하는 과정을 모두 마쳐도 아직 실행 컨텍스트가 관여할 코드들은 실행되기 전의 상태이다.
즉, 자바스크립트는 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다.
여기서 끌어리는 것을 호이스팅(hoisting)이라고 한다.
function a(x) {
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a(1)
위의 코드에서 우르는 순서대로 1, undefined, 2 가 출력될 것이라고 생각한다.
하지만 실제로 그렇지 않다. 호이스팅을 거치기 때문이다.
식별자에는 매개변수 이름, 함수 선언, 변수명 등이 있음을 기억하면서 식별자를 하나씩 호이스팅 해보자.
// 1. 매개변수를 호이스팅한다.
function a() {
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a()
// 2. 변수명을 호이스팅한다. ('선언부'만 호이스팅 )
function a() {
var x;
var x = 1;
console.log(x);
console.log(x);
var x = 2;
console.log(x);
}
a()
<output>
1
1
2
function a() {
console.log(b);
var b = 'bbb';
console.log(b);
function b() {}
console.log(b);
}
a()
<예상 output>
에러 또는 undefined
'bbb'
function b() {}
// 1. 변수명과 함수를 호이스팅한다.
// 변수명은 선언부만 함수는 전체를 호이스팅한다.
function a() {
var b;
function b() {}
console.log(b);
b = 'bbb';
console.log(b);
console.log(b);
}
a()
// 2. 함수 선언문은 함수명으로 선언한 변수에 함수를 할당한 것으로 여긴다.
function a() {
var b;
var b = function b() {}
console.log(b);
b = 'bbb';
console.log(b);
console.log(b);
}
a()
<output>
function b() {}
'bbb'
'bbb'
코어 자바스크립트(Core JavaScript)
https://book.naver.com/bookdb/book_detail.nhn?bid=15433261