호이스팅
호이스팅
개요
호이스팅(Hoisting)은 JavaScript의 컨텍스트 생성 단계에서 변수와 함수의언을 해당 스코프의 최상단으로 "끌어올리는" 것처럼 동작하는 특수한 메커니즘을 의미합니다. 이 개념은 JavaScript의 동작 방식을 이해하는 데 매우 중요하며, 특히 변수 선언과 초기화의 시점이 다를 경우 예기치 않은 동작을 유발할 수 있습니다. 호이스팅은 실제로 코드가 물리적으로 이동하는 것은 아니지만, JavaScript 엔진이 코드를 해석하는 방식 때문에 마치 그랬던 것처럼 보입니다.
이 문서에서는 호이스팅의 정의, 동작 원리, 변수 선언 방식별 차이([var](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/var)
, [let](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/let)
, [const](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/JavaScript/const)
), 함수 호이스팅, 그리고 주의사항과 모범 사례에 대해 자세히 설명합니다.
호이스팅의 동작 원리
JavaScript는 코드 실행 전에 실행 컨텍스트(Execution Context)를 생성합니다. 이 과정은 두 단계로 나뉩니다:
- Creation Phase (생성 단계): 변수와 함수의 선언을 메모리에 할당하고, 변수는
undefined
로 초기화됩니다. - Execution Phase (실행 단계): 코드를 한 줄씩 실행하며 실제 값의 할당과 연산을 수행합니다.
호이스팅은 이 생성 단계에서 발생합니다. 즉, 변수나 함수가 코드 어디에 선언되었든, JavaScript 엔진은 그 선언을 스코프의 맨 위로 "끌어올린다"고 간주합니다.
예제: var
로 선언한 변수의 호이스팅
console.log(name); // undefined
var name = "김철수";
위 코드는 다음과 같은 방식으로 해석됩니다:
var name; // 선언이 호이스팅됨 (undefined로 초기화)
console.log(name); // undefined
name = "김철수"; // 할당
이처럼 var
로 선언된 변수는 선언이 호이스팅되고, 초기값으로 undefined
를 가집니다.
변수 선언 방식별 호이스팅 동작
JavaScript에서는 var
, let
, const
세 가지 방식으로 변수를 선언할 수 있으며, 각각의 호이스팅 동작이 다릅니다.
1. var
- 호이스팅 + undefined
- 선언과 초기화가 분리됨.
- 호이스팅 시
undefined
로 초기화됨. - 함수 스코프를 가짐.
console.log(a); // undefined
var a = 10;
2. let
과 const
- 호이스팅은 되지만 초기화되지 않음 (Temporal Dead Zone)
let
과const
도 호이스팅됩니다.- 하지만 초기화(initialization)가 실행되기 전까지 접근할 수 없습니다.
- 이를 일시적 사각지대(Temporal Dead Zone, TDZ)라고 합니다.
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
✅ 주의:
let
과const
는 호이스팅이 되지만, 선언 전에 참조하면ReferenceError
가 발생합니다.
함수 호이스팅
함수도 호이스팅의 대상이 되지만, 함수 선언 방식에 따라 동작이 다릅니다.
1. 함수 선언 (Function Declaration)
- 전체 함수 정의가 호이스팅됨.
- 선언 이전에 호출 가능.
sayHello(); // "안녕하세요!"
function sayHello() {
console.log("안녕하세요!");
}
2. 함수 표현식 (Function Expression)
var
로 정의된 함수 표현식은 변수처럼 동작.
sayHi(); // TypeError: sayHi is not a function
var sayHi = function() {
console.log("안녕!");
};
let
/const
로 정의된 경우 TDZ로 인해ReferenceError
.
sayBye(); // ReferenceError
let sayBye = function() {
console.log("안녕히 가세요!");
};
호이스팅의 스코프
호이스팅은 함수 스코프 또는 블록 스코프 내에서 발생합니다.
var
: 함수 스코프 → 블록 내 선언이라도 함수 전체에서 유효.let
,const
: 블록 스코프 →{}
내에서만 유효.
function example() {
if (true) {
var x = 1;
let y = 2;
}
console.log(x); // 1 (var는 함수 스코프)
console.log(y); // ReferenceError (let는 블록 스코프)
}
주의사항 및 모범 사례
- 항상 변수를 최상단에 선언하기:
var
사용 시 호이스팅으로 인한 혼란을 줄이기 위해 함수의 맨 위에 변수를 선언하는 것이 좋습니다. let
과const
사용 권장: 호이스팅 관련 오류를 줄이기 위해var
대신let
과const
를 사용하세요.- 선언 전에 사용하지 않기: TDZ를 피하고 코드의 가독성을 높이기 위해 변수는 항상 사용 전에 선언하고 초기화하세요.
- 함수 표현식보다 선언식 선호: 호이스팅을 활용해 함수를 선언 이전에 호출하려면 함수 선언식을 사용하세요.
관련 문서 및 참고 자료
- MDN Web Docs - Hoisting
- ECMAScript Language Specification
- You Don't Know JS (book series) - Scope & Closures
결론
호이스팅은 JavaScript의 중요한 실행 메커니즘 중 하나로, 변수와 함수의 선언이 스코프의 시작 부분에서 처리된다는 점을 이해하는 것이 코드의 예측 가능성을 높이는 데 핵심입니다. 특히 var
와 let
/const
의 차이, TDZ 개념을 숙지하면 버그를 사전에 방지할 수 있습니다. 현대 JavaScript 개발에서는 let
과 const
를 기본으로 사용하고, 호이스팅을 의도적으로 활용하기보다는 명확한 선언 순서를 유지하는 것이 바람직합니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.