호이스팅(Hoisting)이란?
- Hoist: 감아올리다
호이스팅(Hoisting)은 JavaScript에서 변수와 함수의 선언이 실행 전에 해당 스코프의 최상단으로 끌어올려지는 것처럼 동작하는 현상을 말한다.
즉, 코드가 실행되기 전에 JavaScript 엔진이 변수와 함수 선언을 미리 메모리에 등록하기 때문에, 코드에서 선언보다 먼저 참조해도 오류가 발생하지 않을 수 있다.
호이스팅의 원리
JavaScript 코드는 실행되기 전에 두 가지 단계로 처리된다.
- 컴파일 단계(Preparation Step)
- 코드 실행 전에 변수와 함수의 선언을 미리 메모리에 저장.
- var, let, const로 선언된 변수들은 호이스팅되지만, 초기화는 이 단계에서 되지 않음.
- 함수 선언문(Function Declaration)은 전체 함수가 메모리에 올라감.
- 실행 단계(Execution Step)
- 변수의 할당(Assignment)이 실제 코드가 실행되는 순서대로 수행됨.
호이스팅이 발생하는 이유
JavaScript 엔진은 코드를 실행하기 전에 컴파일(혹은 해석) 단계를 거친다.
이 과정에서 엔진은 코드 내의 모든 변수와 함수 선언을 미리 파악하여, 실행 컨텍스트(Execution Context)를 구성한다.
실제 코드 실행 시점에서 변수나 함수를 찾는 데에 혼란이 없도록 하기 위함이다.
1. 함수 선언의 호이스팅
함수 선언문(Function Declaration)은 코드 어디서 작성되었든 상관없이, 실행 전에 메모리에 등록된다.
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
예를 들어 위 코드는 sayHello 함수가 실제 코드상의 위치보다 위에 호출되어도 정상적으로 실행된다.
왜냐하면 함수 선언문은 호이스팅되어 스크립트가 실행되기 전에 이미 메모리에 올라가기 때문이다.
2. 변수 선언의 호이스팅 (var)
var로 선언한 변수의 선언 부분만 호이스팅된다.
변수의 초기화(할당)는 원래 위치에서 이루어집니다.
console.log(myVar); // undefined (선언은 되었지만, 아직 값이 할당되지 않았음)
var myVar = 10;
console.log(myVar); // 10
여기서 myVar의 선언은 최상단으로 끌어올려지지만, 값 10의 할당은 코드의 원래 위치에서 수행되므로, 첫 번째 출력은 undefined가 된다.
3. let과 const의 경우
let과 const로 선언한 변수들도 호이스팅되지만 초기화되지 않은 상태로 존재하며,
Temporal Dead Zone (TDZ) 라는 영역에 놓여서 실제 선언문에 도달하기 전까지 접근할 수 없다.
console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization
let myLet = 20;
4. 함수 표현식의 경우
함수 표현식(Function Expression)으로 정의된 함수는 변수에 할당되는데,
이 변수 선언은 호이스팅되지만, 함수 자체의 값은 할당되지 않은 상태이다.
console.log(myFunc); // undefined
var myFunc = function() {
console.log("Hi!");
};
// myFunc(); // 이 시점에서 호출하면 에러가 발생하지 않지만, "undefined" 상태이므로 함수 호출 불가
⚠️ 정리: var, let, const 비교
변수 키워드 | 호이스팅 | 초기화 전 접근 가능 여부 | 값 할당 시점 | ||||
var | O (선언만) | O (undefined) | 원래 코드 위치에서 초기화됨 | ||||
let | O (선언만) | X (ReferenceError) | 원래 코드 위치에서 초기화됨 (TDZ 영향 O) | ||||
const | O (선언만) | X (ReferenceError) | 원래 코드 위치에서 초기화됨 (TDZ 영향 O) | ||||
함수 선언문 | O (함수 전체) | O | 함수 전체가 초기화됨 (즉시 사용 가능) | ||||
함수 표현식 (var) | O (변수 선언만) | X (TypeError) | 원래 코드 위치에서 초기화됨 |
요약
- 함수 선언문: 완전히 호이스팅되어, 실제 코드 위치와 상관없이 호출할 수 있음.
- var 변수: 선언은 호이스팅되지만, 초기화는 원래 위치에서 이루어져서, 초기에는 undefined 값을 가짐.
- let, const 변수: 호이스팅되지만 TDZ 때문에 선언 전에 접근하면 에러 발생.
- 함수 표현식: 변수 선언은 호이스팅되지만, 함수 할당은 원래 위치에서 이루어짐.
이런 호이스팅 개념을 이해하면, 왜 일부 코드에서는 선언보다 먼저 변수를 사용하거나 함수를 호출해도 문제가 발생하지 않는지, 그리고 언제 에러가 발생하는지를 명확하게 이해할 수 있다.
호이스팅을 안전하게 사용하는 방법
✅ let과 const를 사용하여 변수 선언
✅ 함수 표현식이 필요한 경우 const를 사용하여 선언 후 사용
✅ 변수를 사용하기 전에 선언 위치를 명확히 할 것
💡 "호이스팅이 있다고 해도, 선언보다 먼저 변수를 사용하지 않는 것이 좋은 습관!"
'공공연히 개발하기 🧑💻 > JavaScript' 카테고리의 다른 글
[React] 리액트 프로젝트 환경 관리 (0) | 2025.03.14 |
---|---|
[React] 컴포넌트 선언 방식 비교 export default vs const (0) | 2025.03.14 |
[JavaScript] 함수표현식(Function Expression)이란? (0) | 2025.02.13 |