앞에서 자바스크립트 동작원리를 알아보며 자바스크립트 v8 엔진의 콜스택과 메모리힙에 대해 공부했었다.
이 때 간략하게 원리를 이해하기 위해 '콜스택에는 실행 함수가 들어간다' 라고 간략하게 표현했지만 실제로는 실행 컨텍스트(Execution Context) 가 들어간다.
( ex. 코드가 실행되면 global Execution Context 가 담기고 함수 A가 실행되면 함수 A의 Execution Context가 담기고,, 함수 B가 실행되면 함수 B의 Execution Context가 담기고,, 이런식 ! )
코드를 실행하는데 필요한 환경을 제공하는 객체
V.E와 L.E는 환경레코드와 outer를 가지고 있는데 V.E는 컨텍스트 최초 실행 시점의 스냅샷을 유지하지만, L.E는 변경사항이 반영된다.
이 때 활성화 된 실행 컨텍스트(Running execution context)는 위에서 콜스택을 바라봤다고 생각했을 때 가장 먼저 보이는 = 가장 위에 있는 스택프레임이다.
호이스팅을 다루기 전에 변수의 생성과정을 먼저 살펴보려고 한다.
자바스크립트에서 변수의 생성과정은 3단계로 진행된다.
1. 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체(Variable Object)에 등록한다.
2. 초기화 단계(Initialization phase) : 변수 객체(Variable Object)에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 초기화된다.
3. 할당 단계(Assignment phase) : undefined로 초기화된 변수에 실제 값을 할당한다.
변수 선언문이 최상단으로 끌어올려진 듯한 현상
물리적으로 최상단에 끌어올려지는 것이 아니라 자바스크립트 엔진이 먼저 전체코드를 스캔하면서 변수와 같은 정보들을 실행컨텍스트의 Environment Record 에 저장해놓기 때문이다.
console.log(hi); //undefined 출력
var hi="hello";
console.log(hi); // hello 출력
hi();
var hi=()=>{
//do hi
}
전역 컨텍스트 속 환경 레코드에는 {hi:undefined}로 선언과 초기화가 일어남. undefined는 호출될 수 없기 때문에 type error 가 발생 { hi : undefined }
hi();
const hi=()=>{
//do hi
}
변수 호이스팅의 let, const 와 동일하게 동작함. reference error 발생 { hi }
hi();
function hi(){
//do hi
}
키워드로 함수를 선언하는 경우 선언과 동시에 환경레코드에는 study:f() 와 같이 완성된 함수 객체를 기록함. 즉, 에러없이 실행된다. 이러한 경우 선언 없이도 함수를 사용할 수 있게 되기 때문에 지양하고자 하는 목소리도 있다고 한다. { hi : f() }
Outer Environment Reference : 바깥 lexical environment 를 가리킴.
let lamp=fasle;
function goTo2F(){
let lamp=true;
function goTo3F(){
let pet='puppy';
console.log(pet);//puppy
console.log(lamp);//true
console.log(brie);//reference error
}
goTo3F();
}
goTo2F();
이러한 경우, 자바스크립트 엔진은 lamp의 값을 무엇으로 결정할지 고민에 빠진다. 이렇게 변수나 함수의 값을 결정하는 것을 '식별자 결정' 이라고 한다.
outer는 쉽게 추상화하여 n-1층의 스택프레임과 n층의 스택프레임을 연결하는 사다리 정도로 생각할 수 있다.
위의 코드의 형태라면,
3층엔 goTo3F의 함수 컨텍스트
2층엔 goTo2F의 함수 컨텍스트
1층엔 전역컨텍스트
가 자리를 잡고 있는 3층집의 구조와 비슷해지는 것이다.
동일한 식별자로 인해 2번의 lamp를 출력하는 코드를 실행하면 상위 스코프에서 선언된 식별자의 값이 가려지게 되는데 이를 '변수 섀도잉' 이라고 부른다. 또한 이렇게 사다리(outer)를 통해 변수를 찾고 찾아나가는 과정 자체를 '스코프 체이닝'이라고 부른다.