들어가며
JavaScript를 배우다 보면 선언하기 전에 변수를 사용해도 오류가 나지 않는 이상한 경험을 하게 됩니다.
이 현상의 원인이 바로 호이스팅(Hoisting) 입니다.
이 글에서는 호이스팅이 무엇인지, 변수와 함수에서 어떻게 다르게 동작하는지 정리해보겠습니다.
호이스팅이란?
호이스팅은 코드가 실행되기 전에 모든 변수 선언과 함수 선언을 메모리에 미리 저장하는 동작입니다.
마치 선언부가 코드의 맨 위로 끌어올려진 것처럼 동작하기 때문에 "끌어올리기"라고도 합니다.
// 실제 작성한 코드
console.log(name); // undefined
var name = "홍길동";
console.log(name); // "홍길동"
// 자바스크립트 엔진이 실행하는 방식 (호이스팅)
var name; // 선언부가 맨 위로 끌어올려짐
console.log(name); // undefined - 선언은 됐지만 값은 아직 없음
name = "홍길동"; // 값 할당은 원래 위치에서 실행
console.log(name); // "홍길동"
변수 호이스팅
var - 선언만 호이스팅, 값은 undefined
var로 선언한 변수는 선언부만 호이스팅되고, 값 할당은 원래 위치에서 이루어집니다.
선언 전에 접근하면 오류가 아닌 undefined가 반환됩니다.
console.log(age); // undefined (오류 아님!)
var age = 25;
console.log(age); // 25
let, const - 호이스팅되지만 접근 불가 (TDZ)
let과 const도 호이스팅은 되지만, 선언 전에 접근하면 ReferenceError가 발생합니다.
선언 전 접근이 금지된 구간을 TDZ(Temporal Dead Zone, 일시적 사각지대) 라고 합니다.
console.log(name); // ReferenceError! - TDZ 구간
let name = "홍길동";
console.log(name); // "홍길동"
[TDZ 구간]
let name 선언 위치 이전 ← 이 구간에서 name에 접근하면 오류
↓
let name = "홍길동" ← 선언 및 초기화 시점부터 접근 가능
↓
console.log(name) ← 정상 접근
함수 호이스팅
함수 선언식 - 전체가 호이스팅
함수 선언식은 함수 전체(선언 + 내용)가 호이스팅됩니다.
선언 전에 호출해도 정상적으로 동작합니다.
// 선언 전에 호출
greet(); // "안녕하세요!" - 정상 실행
// 함수 선언식
function greet() {
console.log("안녕하세요!");
}
함수 표현식 - 변수와 동일하게 동작
함수를 변수에 담는 함수 표현식은 변수 호이스팅 규칙을 따릅니다.var로 선언하면 undefined, let/const로 선언하면 ReferenceError가 발생합니다.
// 선언 전에 호출
greet(); // TypeError! - undefined는 함수가 아님
var greet = function() {
console.log("안녕하세요!");
};
var / let / const / 함수선언식 호이스팅 비교
| 구분 | 호이스팅 여부 | 선언 전 접근 | 결과 |
|---|---|---|---|
var |
선언부만 호이스팅 | 가능 | undefined |
let |
호이스팅되나 TDZ | 불가 | ReferenceError |
const |
호이스팅되나 TDZ | 불가 | ReferenceError |
| 함수 선언식 | 전체 호이스팅 | 가능 | 정상 실행 |
| 함수 표현식 | 변수 규칙 따름 | 불가 (let/const) | ReferenceError |
호이스팅이 생기는 이유
JavaScript 엔진은 코드를 실행하기 전에 실행 컨텍스트(Execution Context) 를 생성합니다.
이 과정에서 변수 선언과 함수 선언을 먼저 메모리에 등록하기 때문에 호이스팅이 발생합니다.
[실행 순서]
1단계 - 생성 단계 (코드 실행 전)
→ 모든 var 변수 선언을 메모리에 등록 (값: undefined)
→ 모든 함수 선언식을 메모리에 등록 (함수 전체)
→ let, const도 등록하지만 TDZ로 접근 차단
2단계 - 실행 단계 (코드 실행)
→ 위에서 아래로 순서대로 실행
→ 값 할당, 함수 호출 등 실제 동작 수행
호이스팅으로 생기는 실수
var의 호이스팅은 예상치 못한 버그를 만들기 쉽습니다.
// 의도: 조건에 따라 다른 값 사용
if (false) {
var result = "실행됨";
}
console.log(result); // undefined - 오류가 아님!
// var는 블록 스코프가 없어 if 밖에서도 접근 가능
이런 이유로 현대 JavaScript에서는 var 대신 let과 const 사용을 권장합니다.
// 올바른 습관
const name = "홍길동"; // 재할당 없으면 const
let age = 25; // 재할당 필요하면 let
// var는 사용하지 않는 것이 좋음
정리
- 호이스팅은 코드 실행 전에 변수 선언과 함수 선언을 메모리에 미리 저장하는 동작이다.
var는 선언부만 호이스팅되어 선언 전에 접근하면undefined가 반환된다.let과const는 호이스팅되지만 TDZ로 인해 선언 전에 접근하면ReferenceError가 발생한다.- 함수 선언식은 함수 전체가 호이스팅되어 선언 전에도 호출이 가능하다.
- 예상치 못한 버그를 방지하기 위해
var대신let과const를 사용하는 것이 좋다.
'-- 오늘 있었던 개발 일기' 카테고리의 다른 글
| React의 장점 - 빠른 렌더링? 개발자 관점에서의 효율성 (0) | 2026.05.29 |
|---|---|
| @Controller란? - Spring 자동 매핑과 Bean 등록 (0) | 2026.05.06 |
| 인터프리터 언어란? (0) | 2026.04.13 |
| 컴파일 언어란? - 그리고 Java는 어떻게 다를까? (0) | 2026.04.12 |
| 매개변수(Parameter)란? (1) | 2026.04.11 |