자바스크립트 호이스팅이란? var, let, const, 함수 차이까지
자바스크립트 호이스팅이란?
자바스크립트 호이스팅(hoisting)이란 변수와 함수의 선언이 코드 실행 전에 자신이 속한 스코프의 맨 위로 끌어올려지는 것처럼 동작하는 자바스크립트의 특성을 말합니다. 정확히는 코드가 물리적으로 이동하는 것이 아니라, 자바스크립트 엔진이 실행에 앞서 선언들을 먼저 메모리에 등록하기 때문에 "끌어올려진 것처럼" 보이는 것입니다. 그래서 선언보다 위에서 변수를 참조해도 오류가 나지 않는 경우가 생깁니다.
console.log(x); // undefined (오류 아님!)
var x = 5;
console.log(x); // 5
// 엔진이 이해하는 방식:
// var x; // 선언만 위로 끌어올려짐
// console.log(x); // undefined
// x = 5; // 할당은 원래 자리에서
// console.log(x); // 5var의 호이스팅: 선언만 올라가고 값은 undefined
var로 선언한 변수는 호이스팅되며, 끌어올려진 시점에는 값이 undefined로 초기화됩니다. 그래서 할당 전에 접근해도 에러 대신 undefined가 나옵니다. 이 동작이 버그를 만들기 쉽습니다.
let과 const의 호이스팅: TDZ
흔한 오해와 달리 let과 const도 호이스팅됩니다. 다만 선언 전에는 접근할 수 없는 "일시적 사각지대(Temporal Dead Zone, TDZ)"에 머뭅니다. 이 구간에서 변수를 읽으려 하면 undefined가 아니라 ReferenceError가 발생합니다.
console.log(a); // ReferenceError (TDZ)
let a = 10;
console.log(b); // ReferenceError (TDZ)
const b = 20;덕분에 let/const는 var보다 안전합니다. 선언 전에 실수로 변수를 쓰면 조용히 undefined가 되는 대신 명확한 에러로 알려 주기 때문입니다.
함수의 호이스팅: 선언문 vs 표현식
함수는 정의 방식에 따라 호이스팅 결과가 다릅니다.
// 함수 선언문: 통째로 호이스팅 → 위에서 호출 가능
sayHi(); // "안녕!" 정상 동작
function sayHi() {
console.log('안녕!');
}
// 함수 표현식: 변수 규칙을 따름
sayBye(); // TypeError: sayBye is not a function
var sayBye = function () {
console.log('잘가!');
};함수 표현식을 let/const로 쓰면 TDZ 때문에 ReferenceError가 납니다. 화살표 함수도 표현식이라 같은 규칙을 따릅니다.
한눈에 보는 호이스팅 비교
| 선언 종류 | 호이스팅 | 선언 전 접근 시 |
|---|---|---|
| var | O (undefined로 초기화) | undefined |
| let | O (TDZ) | ReferenceError |
| const | O (TDZ) | ReferenceError |
| 함수 선언문 | O (함수 전체) | 정상 호출 가능 |
| 함수 표현식 | 변수 규칙 따름 | TypeError 또는 ReferenceError |
흔한 실수
- let/const는 호이스팅 안 된다는 오해: 호이스팅은 되지만 TDZ 때문에 접근할 수 없을 뿐입니다.
- var의 함수 스코프 혼동: var는 블록(
{ })이 아니라 함수 단위로 스코프가 잡혀,if나for블록 밖에서도 접근됩니다. let/const는 블록 스코프입니다. - 함수 표현식을 선언문처럼 위에서 호출: 표현식은 할당 전에는 함수가 아니므로 호출하면 에러가 납니다.
자주 묻는 질문
Q1. 호이스팅을 일부러 활용해도 되나요?
권장하지 않습니다. 변수와 함수는 사용하기 전에 선언하는 것이 가독성과 안정성에 좋습니다. 현대 코드에서는 let/const를 쓰고 선언 후 사용하는 습관을 들이세요.
Q2. let과 const를 쓰면 호이스팅 걱정을 안 해도 되나요?
TDZ 덕분에 선언 전 접근이 에러로 막혀 더 안전하지만, 호이스팅 자체는 여전히 일어납니다. 원리를 알아 두면 ReferenceError의 원인을 빠르게 파악할 수 있습니다.
Q3. 함수 선언문과 화살표 함수, 호이스팅이 어떻게 다른가요?
함수 선언문은 전체가 호이스팅되어 선언 위에서도 호출할 수 있습니다. 화살표 함수는 변수에 할당되는 표현식이라 변수 호이스팅 규칙(var는 undefined, let/const는 TDZ)을 따릅니다.