🌈 인프런의
코어 자바스크립트(정재남)
수강 후, 이해한 내용을 정리한 글입니다.
함수를 실행하는데 필요한 조건/환경정보를 담은 객체
이다. Execution Context는 Call Stack에 쌓인다.
이렇게 생각해 보자. 파란 박스가 Call Stack이고 흰색 박스가 Execution Context라고 생각하자.
아래 코드를 실행하면
function outer() {
function inner() {
// ...생략...
}
inner()
}
outer()
이런 순으로 Call Stack에 Execution Context가 쌓이고 빠진다.
알다시피 흰 상자는 Execution Context이다. Execution Context 안에는 VariableEnvironment, LexicalEnvironment, ThisBinding이 있다.
여기서 중요한 것은 LexicalEnvironment
이다.
environmentRecord
와 outerEnvironmentReference
이다.
1) environmentRecord: 호이스팅
내부
environmentRecord를 키워드로 설명하면 호이스팅
, 내부
이다.
📍호이스팅
호이스팅이란 식별자 정보를 끌어올리는 것이다. 호이스팅은 코드 실행 전에 발생한다.
📍내부
호이스팅 과정에서 environmentRecord는 해당 Context 내부
의 식별자 정보를 수집한다. 예를 들면, 왼쪽 코드는 호이스팅을 통해 오른쪽 코드로 변화한다.(함수는 함수 전체가, 나머지는 선언만 위로 끌어올려진다.)
이 과정에서 environmentRecord에는 아래의 정보가 담긴다.
이러한 정보는 호이스팅된 식별자 정보와 동일하다.
정리하면, environmentRecord에는 호이스팅
을 통해 수집된 현재 Context 내부
의 식별자 정보가 저장된다.
2) outerEnvironmentReference: 외부
스코프 체인
outerEnvironmentReference를 키워드로 설명하면 외부
, 스코프 체인
이다.
📍외부
outerEnvironmentReference는 현재 Context의 외부
LexicalEnvironment를 참조하는 것이다. 예를 들면, 아래 그림에서 왼쪽은 앞의 예시 코드에서 가져온 Call Stack이고 왼쪽을 구체적으로 그리면 오른쪽 그림이 된다.
오른쪽 그림을 자세히 살펴보자.
각각의 outerEnvironmentReference는 각각의 상위의 LexicalEnvironment를 참조한다. 따라서 각 Context들은 environmentRecord를 통해 각 Context에서 선언된 내부 식별자에 접근할 수 있을 뿐만 아니라 outerEnvironmentReference를 통해 외부
식별자에도 접근 가능하다.
결국, 핵심은 위의 그림에서 파란 박스의 Execution Context는 파란 박스 내부에서 선언된 식별자뿐만 아니라 그를 넘어선 노란 막대 영역의 외부
식별자까지 접근 가능하다는 것이다. 이러한 특성 때문에 outerEnvironmentReference에 의해 스코프 체인이 만들어진다.
📍스코프 체인
스코프 체인은 현재 실행중인 Context와 상위 스코프들의 연결된 구조를 말한다. 예를 들면, 아래 그림처럼 모든 Execution Context에 변수 a가 선언되어 있고, Inner Execution Context에서 console.log(a)
를 실행했다고 가정하자. 그러면 console.log(a)
는 본인 Context에서 선언된 var a = 1
에 접근하여 1을 출력한다.
만약 본인 Context에 선언된 a
가 존재하지 않는다면 상위 Context를 참조한다. 아래 그림에서, Outer Execution Context에 선언된 var a = 2
가 있으므로 console.log(a)
는 2를 출력한다.
만약 아래 그림처럼 Outer Execution Context에도 선언된 a
가 없다면 또 한 번 상위 Context를 탐색하여 console.log(a)
는 3을 출력한다.
정리하면, outerEnvironmentReference로 인해 각 Context는 외부
식별자에 접근 가능하고, 그로 인해 스코프 체인
이 발생한다는 것이다.
Q. 각 console.log(a)에서 출력되는 값은?
var a = 1
function outer() {
console.log(a)
function inner() {
console.log(a)
var a = 3
}
inner()
console.log(a)
}
outer()
console.log(a)
A. 정답
var a = 1
function outer() {
console.log(a) // 1
function inner() {
console.log(a) // undefined(호이스팅으로 a가 선언만 되고 할당은 안 되어 있기 때문)
var a = 3
}
inner()
console.log(a) // 1
}
outer()
console.log(a) // 1
호이스팅
을 통해 내부
식별자 정보를 저장하고, outerEnvironmentReference는 외부
LexicalEnvironment를 참조하여 스코프 체인
을 형성한다.