호이스팅(Hoisting)은 js 엔진이 코드를 실행하기 전에 변수 및 함수 선언문이 스코프 내의 최상단으로 끌어 올려지며, 메모리에 먼저 할당되는 현상입니다. 중요한 것은 선언문이 끌어올려지고 대입문은 끌어올려지지 않는다는 것입니다.
var로 선언된 변수는 선언부만 호이스팅되고, 초기화는 원래 코드에 작성된 위치에서 이루어집니다.
console.log(name); // undefined
var name = "홍길동";
console.log(name); // 홍길동
let과 const로 선언된 변수도 호이스팅됩니다. 하지만 TDZ때문에 초기화 전에 접근하면 에러가 발생합니다.
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 30;
함수는 선언문 전체가 호이스팅됩니다. 따라서 선언 전에도 함수를 호출할 수 있습니다.
sayHello(); // 안녕하세요
function sayHello() {
console.log('안녕하세요');
}
함수 표현식은 변수 호이스팅과 동일한 규칙을 따릅니다. 변수만 호이스팅되고 함수 할당은 코드 실행 시점에 이루어집니다.
greeting(); // TypeError: greeting is not a function
var greeting = function() {
console.log("반갑습니다!");
};
클래스 선언도 호이스팅되지만, let과 const처럼 TDZ의 영향을 받습니다.
TDZ(Temporal Dead Zone)는 변수가 선언되었지만 아직 초기화되지 않은 상태로, 해당 변수에 접근할 수 없는 영역을 말합니다.
let과 const로 선언된 변수는 선언 지점부터 초기화 전까지 TDZ에 있어 접근할 수 없습니다. 이는 var와 달리 undefined를 반환하지 않고 명시적으로 ReferenceError를 발생시켜 더 예측 가능한 코드를 작성할 수 있게 합니다.
var: 함수 스코프, 재선언 가능, 재할당 가능, 호이스팅 시 undefined로 초기화
let: 블록 스코프, 재선언 불가, 재할당 가능, TDZ 적용
const: 블록 스코프, 재선언 불가, 재할당 불가, TDZ 적용
호이스팅은 js의 특성이자 때로는 혼란을 주는 요소입니다. 이 개념을 정확히 이해하면 예상치 못한 버그를 방지하고 더 안정적인 코드를 작성할 수 있습니다. var 대신 let과 const를 사용해 더 예측 가능한 스코프 동작을 확보할 수 있습니다.