호이스팅(hoisting)은 JavaScript에서 변수와 함수 선언이 스코프의 최상단으로 끌어올려진 것처럼 동작하는 특징입니다.
코드 자체가 이동하는 것은 아니며, JavaScript 엔진이 실행 전에 평가 단계를 거쳐 선언을 먼저 처리하기 때문에 발생합니다.
호이스팅은 크게 변수 호이스팅과 함수 호이스팅으로 나뉩니다.
var로 선언된 변수는 선언만 호이스팅되며, 해당 변수는 undefined로 초기화됩니다. 따라서 변수 선언 전에 접근해도 에러 대신 undefined가 출력됩니다.
console.log(x); // undefined
var x = 10;
console.log(x); // 10
반면, ES6에서 도입된 let과 const는 호이스팅이 발생하지만, 선언 전에 변수에 접근하면 TDZ(Temporal Dead Zone)로 인해 ReferenceError가 발생합니다.
호이스팅이 발생하지만, 변수 접근만 불가합니다.
console.log(x); // ReferenceError
// TDZ 끝
const x = 10;
console.log(x); // 10
TDZ(Temporal Dead Zone)
let과 const는 변수가 선언되기 전까지 초기화되지 않습니다.
이 구간을 TDZ라고 하며, TDZ 내에서 변수에 접근하면 ReferenceError가 발생합니다.
반면, var는 선언과 동시에 undefined로 초기화되므로 TDZ가 없습니다.
함수 선언식(function myFunction() {})은 함수 선언과 정의가 함께 호이스팅되므로, 선언 전에 호출해도 정상적으로 실행됩니다.
console.log(myFunction()); // 'Hello World'
function myFunction() {
return 'Hello World';
}
반면, 함수 표현식은 변수에 함수를 할당하는 방식이므로 변수 선언 방식에 따라 동작이 달라집니다. var로 선언된 경우 변수 선언만 호이스팅되어 undefined가 출력되며, let이나 const로 선언된 경우 TDZ에 의해 ReferenceError가 발생합니다.
console.log(myFunction); // undefined
var myFunction = () => {
return 'Hello World';
};
console.log(myFunction()); // 'Hello World'
| 선언 타입 | 호이스팅 여부 | 초기화 여부 | 선언 전 접근 결과 |
|---|---|---|---|
| var | O | undefined | undefined |
| let | O (TDZ) | X | ReferenceError |
| const | O (TDZ) | X | ReferenceError |