참조
호이스팅이란
Lexical Environment
Lexical Environment의 대략적인 구조
호이스팅의 예시
함수 선언식의 호이스팅
// 아래 예시처럼 선언부가 사용부보다 밑에 있지만 정상적인 접근 가능
helloWorld();
function helloWorld() {
console.log("Hello World");
}
// 위 코드가 실행되는 과정에서 Lexical Environment의 상황
// 아래처럼 메모리에 매핑되어 접근 가능
LexicalEnvironment = {
helloWorld: <function object>
}
함수 표현식의 호이스팅
// 아래처럼 함수를 선언하지 않고 표현식을 사용하는 경우 접근 불가능
// 함수 표현식을 사용하는 경우 함수 표현식이 먼저 작성되어야 접근 가능
helloWorld(); // TypeError: helloWorld is not a function
// let, const로 선언하는 경우 에러 내용이 달라짐
// var -> TypeError: helloWorld is not a function(undefined로 초기화)
// let, const -> ReferenceError: Cannot access 'helloWorld' before initialization
var helloWorld = function() {
console.log("Hello World");
}
함수 선언식/표현식에 따라 달라지는 이유
호이스팅이 이뤄지는 과정
var
var로 변수는 호이스팅이 이뤄지지 않음
정확히는 선언은 호이스팅되지만 초기화를 할당하지 않음
컴파일 단계에서 var 변수 선언을 찾아 LexicalEnvironment에 저장하고 undefined로 초기화를 수행
이후 코드를 실행하는 과정에서 할당하는 코드에 도달했을 때 JavaScript엔진은 변수에 값을 할당
예시 코드
// var 변수의 사용
console.log(a); // undefined
var a = 3;
// var 변수를 사용하는 경우의 Lexical Environment
LexicalEnvironment = {
a: undefined
}
// 이후 코드 실행을 위해 JavaScritp엔진이 할당 코드에 도달한 경우
LexicalEnvironment = {
a: 3
}
// 아래는 과정을 코드로 나타낸다면
var a;
console.log(a);
a = 3;
let, const
let, const에서는 var과는 다르게 동작
let, const에서는 uninitialized로 LexicalEnvironment에 저장
즉 let, const는 호이스팅이 이뤄지지 않는 다는 말이 있는데, 정확히는 호이스팅은 되지만 undefined로 초기화되지 않고 uninitialized로 남아있음
let, const의 초기화는 오직 JavaScript 엔진이 작동할 때 LexicalBinding이 발생할 때 이루어지며 그전까지는 해당 변수에 접근할 수 없도록 한 것
또한 JavaScript엔진이 작동하기 전까지 접근할 수 없는 시간을 **TDZ(Temporal-Dead-Zone)**라고 함
만약 LexicalBinding에서 let, const 초기화 값을 찾지 못한 경우 undefined로 초기화되거나 const의 경우 에러를 발생(const의 경우 선언과 동시에 초기화가 이뤄져야 함)
예시 코드
let a;
console.log(a); // undefined
a = 3;
const a;
console.log(a); // SyntaxError: Missing initializer in const declaration
a = 3;
class
let, const와 같이 선언 코드를 만나기 전까지는 uninitialized 상태
즉, TDZ의 영향을 받음
예시 코드
let peter = new Person("Perter", 25); // ReferenceError: Cannot access 'Person' before initialization
console.log(peter);
class Person {
consturctor(name, age) {
this.name = name;
this.age = age;
}
}