Rounded avatar

BOBcost

Dev

호이스팅(Hoisting) 완벽정리

자바스크립트에서 변수와 함수 선언이 코드 실행 이전에 끌어올려지는 호이스팅의 원리와 동작 방식을 이해하고 정리합니다.
생성일 : 2025년 08월 22일

호이스팅(Hoisting) 이란?

자바스크립트에서 호이스팅(Hoisting)은 변수 선언과 함수 선언을 코드의 맨 위로 끌어올려지는 현상을 일컫는다.
호이스팅은 ECMAScript 사양에서 규범적으로 정의된 용어가 아닙니다.

호이스팅 간주하는 경우

1. 변수가 선언된 줄 이전에 해당 범위에서 변수 값을 사용할 수 있는 경우

  • ⭐️Point : 범위 안에서 변수가 존재하는 사실 자체가 미리 적용
💡값 호이스팅 예시
console.log(a); // undefined → 값 호이스팅
var a = 10;
console.log(a); // 10

2. 변수가 선언된 줄 이전에 해당 범위의 변수를 참조할 수 있지만 ReferenceError를 던지지 않고 값이 항상 정의되지 않을 경우

  • var는 선언은 끌어올려짐, 값은 끌어올려지지 않음 → 선언 이전 접근 가능하지만 값은 undefined
  • let / const는 선언만 끌어올려지고 초기화 전 접근 시 ReferenceError 발생(TDZ)
  • ⭐️Point : 선언 이전 접근 가능 여부와 TDZ 차이
💡선언 호이스팅
console.log(a) // undefined
var a = 10;
console.log(a) // 10
 
console.log(b); // ReferenceError → let/const는 TDZ 존재
console.log(c); // ReferenceError → let/const는 TDZ 존재
let b = 20;
const c = 30;
console.log(b); // 20
console.log(c) // 30

TDZ (Temporal Dead Zone)? TDZ는 변수가 실제로 선언되기 전까지 접근할 수 없는 영역을 의미합니다.

3. 변수를 선언하면 변수가 선언된 줄 앞의 범위에서 동작이 변경됩니다.

  • ⭐️Point : 선언 이전에 값을 읽을 수 있는 현상, ReferenceError는 발생하지 않음
💡앞의 범위 예시
console.log(msg); // undefined → 선언이 호이스팅됨
var msg = "Hello, world!";
console.log(msg); // "Hello, world!"
console.log(1)

4. 선언의 부작용은 선언이 포함된 나머지 코드를 평가하기 전에 발생합니다.

  • ⭐️Point : 선언이 코드 평가 전에 끌어올려져 나머지 코드에 영향
💡평가 전 예시
console.log(y); // undefined
y = 5;          // 실제 할당
var y;          // 선언이 코드 평가 전에 끌어올려짐
console.log(y); // 5

자바스크립트에서의 변수 처리 단계

  • 선언 단계 (Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록
  • 초기화 단계 (Initialization phase) : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보
  • 할당 단계 (Assignment phase) : undefined로 초기화된 변수에 실제 값 할당단계는 여러가지가 있다

📌 호이스팅 발생 원인
자바스크립트의 변수 생성(Instantiation)과 초기화(Initialization)의 작업이 분리돼서 진행되기 때문이다.

함수 선언식 or 함수 표현식

// 함수 선언식
function add(x, y) {
  return x + y;
}
 
// 함수 표현식
const add = function(x, y) {
  return x + y;
};

자바스크립트에서 함수 표현식은 함수 선언식보다 더 유연합니다. 표현식은 변수를 통해 함수를 동적으로 할당하거나, 콜백 함수와 같이 특정 상황에서만 실행되도록 쉽게 사용할 수 있기 때문입니다.
하지만 디버깅 측면에서는 표현식이 항상 유리한 것은 아닙니다. 함수 선언식은 항상 이름이 붙어 있어서 디버깅할 때 호출 스택에서 식별하기가 더 쉽습니다.

다만, 기명 함수 표현식이나 화살표 함수를 적절히 사용하면 이 문제를 완화할 수 있다.

함수의 호이스팅

함수 선언식 예시
1console.log('위 : ' + add(2, 3)); // 호이스팅 발생❗️
2
3function add(x, y) {
4    return x + y; 
5}
6
7console.log('아래 : ' + add(3, 4));

함수 선언식은 정의 전체가 호이스팅되기 때문에, 함수가 코드 아래에 작성되어 있어도
선언 이전부터 정상적으로 호출할 수 있습니다.

함수 표현식 예시
1console.log(add(2, 3)); // "Error: add is not a function"
2
3// 함수 표현식 형태로 add() 함수 정의
4var add = function (x, y) {
5return x + y;
6
7}
8
9console.log(add(3, 4)); // 7 

이 경우 add 자체는 호이스팅 때문에 undefined로 초기화되어 있습니다.

그래서 실행 시,

  • 자바스크립트는 add(2, 3)을 평가하려고 시도함
  • 그런데 add의 값이 undefined
  • 따라서 “TypeError: add is not a function” 이 발생합니다.

📚 내용 요약

구분호이스팅 여부초기화 시점선언 전 접근 시특징
varundefined 초기화undefined 반환함수 스코프, 선언 전 접근 가능
let선언문 도달 시 초기화 ReferenceError (TDZ)블록 스코프, 안전함
const선언문 도달 시 초기화 ReferenceError (TDZ)블록 스코프, 재할당 불가
함수 선언식 됨 (정의 전체)코드 실행 전 초기화정상 호출 가능선언 전에 호출 가능
함수 표현식 (var)변수만 호이스팅런타임 할당 시undefined → TypeError 발생선언 전 호출 불가
함수 표현식 (let/const)변수만 호이스팅선언문 도달 시 초기화 ReferenceError (TDZ)선언 전 호출 불가

📌 호이스팅은 변수와 함수 선언이 실행 컨텍스트 생성 시점에 메모리에 미리 등록되기 때문에 발생하는 현상입니다.

  • var는 선언과 동시에 undefined로 초기화되어 선언 전에도 접근 가능하지만, 의도치 않은 버그를 유발할 수 있습니다.
  • let과 const는 TDZ 때문에 선언 이전에는 사용할 수 없어 더 안전합니다.
  • 함수 선언식은 전체가 호이스팅되므로 선언 전에 호출 가능하지만, 함수 표현식은 변수의 호이스팅 방식에 따라 동작이 달라집니다.
    따라서 실무에서는 var 대신 let/const, 필요에 따라 함수 표현식을 활용하는 것이 일반적입니다.

🤔 그래서 결론은?

호이스팅은 코드가 위로 올라간 것처럼 보이게 만드는 자바스크립트의 내부 처리 방식으로, 선언 이전에도 존재를 인지하게 하지만 접근 방식에 따라 결과가 달라집니다. 따라서 이를 이해하고 주의하며 사용해야 합니다❗️


참고 자료
  1. https://inpa.tistory.com/entry/JS-📚-스코프-함수-호이스팅 [Inpa Dev 👨‍💻:티스토리]
  2. https://ko.javascript.info/var [모던 Javascript 튜토리얼]
  3. https://developer.mozilla.org/ko/docs/Glossary/Hoisting [MDN]