호이스팅(Hoisting)
중요도: ⭐⭐⭐⭐⭐
JavaScript의 기본 동작 원리로, 변수와 함수 실행 순서를 이해하는 핵심 개념입니다.
호이스팅(Hoisting)
호이스팅(Hoisting)은 변수 선언과 함수 선언이 해당 스코프의 최상단으로 끌어올려지는 JavaScript의 특성입니다.
변수 호이스팅
var 키워드
// 실제 작성한 코드
console.log(myVar); // undefined (에러가 아님!)
var myVar = "Hello World";
console.log(myVar); // "Hello World"
// 호이스팅으로 인해 JavaScript 엔진이 이해하는 코드
var myVar; // undefined로 초기화
console.log(myVar); // undefined
myVar = "Hello World";
console.log(myVar); // "Hello World"var의 특징:
- 변수 선언이 스코프 최상단으로 호이스팅됩니다
- 초기화는 호이스팅되지 않아 undefined 값을 갖습니다
let, const 키워드
// Temporal Dead Zone 때문에 에러 발생
console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization
let myLet = "Hello Let";
console.log(myConst); // ReferenceError: Cannot access 'myConst' before initialization
const myConst = "Hello Const";let, const의 특징:
- 변수 선언은 호이스팅되지만 초기화는 되지 않습니다
- Temporal Dead Zone에 의해 선언 전 접근 시 ReferenceError가 발생합니다
함수 호이스팅
함수 선언문 (Function Declaration)
// 함수 호출이 선언보다 먼저 나와도 정상 동작
sayHello(); // "Hello World!"
function sayHello() {
console.log("Hello World!");
}
// 호이스팅으로 인해 실제로는 이렇게 동작
function sayHello() {
console.log("Hello World!");
}
sayHello(); // "Hello World!"함수 선언문의 특징:
- 함수 전체가 호이스팅되어 선언 전에도 호출 가능합니다
함수 표현식 (Function Expression)
// 함수 표현식은 호이스팅되지 않음
sayHello(); // TypeError: sayHello is not a function
var sayHello = function () {
console.log("Hello World!");
};
// 호이스팅으로 인해 실제로는 이렇게 동작
var sayHello; // undefined로 초기화
sayHello(); // TypeError: sayHello is not a function
sayHello = function () {
console.log("Hello World!");
};함수 표현식의 특징:
- 변수만 호이스팅되고 함수는 호이스팅되지 않습니다
화살표 함수와 호이스팅
// 화살표 함수도 함수 표현식과 동일하게 동작
sayHello(); // TypeError: sayHello is not a function
var sayHello = () => {
console.log("Hello World!");
};복잡한 호이스팅 예시
var x = 1;
function example() {
console.log(x); // undefined (not 1)
var x = 2;
console.log(x); // 2
}
example();
// 호이스팅으로 인해 실제로는 이렇게 동작
var x = 1;
function example() {
var x; // undefined로 초기화 (지역 변수가 전역 변수를 가림)
console.log(x); // undefined
x = 2;
console.log(x); // 2
}
example();스코프와 호이스팅
// 함수 스코프와 호이스팅
function scopeExample() {
if (true) {
var functionScoped = "function scoped";
let blockScoped = "block scoped";
}
console.log(functionScoped); // "function scoped" (var는 함수 스코프)
console.log(blockScoped); // ReferenceError (let은 블록 스코프)
}
// 호이스팅으로 인해 실제로는 이렇게 동작
function scopeExample() {
var functionScoped; // undefined로 초기화되어 함수 스코프 최상단으로 호이스팅
if (true) {
functionScoped = "function scoped";
let blockScoped = "block scoped"; // let은 블록 스코프 내에서만 유효
}
console.log(functionScoped); // "function scoped"
console.log(blockScoped); // ReferenceError
}클래스와 호이스팅
// 클래스는 호이스팅되지 않음
const myInstance = new MyClass(); // ReferenceError: Cannot access 'MyClass' before initialization
class MyClass {
constructor(name) {
this.name = name;
}
}호이스팅 관련 모범 사례
호이스팅 모범 사례
- 변수는 사용하기 전에 선언하기
- const를 우선 사용하고, 필요시 let 사용
- var 사용 피하기 (함수 스코프와 호이스팅으로 인한 혼란 방지)
- 함수 선언문보다는 함수 표현식 사용 (명확한 실행 순서)
실무에서의 호이스팅 활용
// ❌ 나쁜 예시: 호이스팅에 의존
console.log(user); // undefined
processUser(); // 함수는 정상 동작
var user = "John";
function processUser() {
if (!user) {
console.log("No user found");
} else {
console.log(`Processing ${user}`);
}
}
// ✅ 좋은 예시: 명확한 순서
const user = "John";
const processUser = () => {
if (!user) {
console.log("No user found");
} else {
console.log(`Processing ${user}`);
}
};
console.log(user);
processUser();Temporal Dead Zone 상세
// let/const의 Temporal Dead Zone
console.log(typeof myVar); // "undefined"
console.log(typeof myLet); // ReferenceError
var myVar = "var";
let myLet = "let";
// 함수 매개변수와 TDZ
function example(param = anotherParam, anotherParam) {
// ReferenceError: Cannot access 'anotherParam' before initialization
}면접 팁
호이스팅에 대해 질문받을 때는 var, let, const의 차이점과 Temporal Dead Zone 개념을 확실히 이해하고 설명할 수 있어야 합니다. 또한 실무에서 호이스팅으로 인한 버그를 어떻게 해결했는지, 어떤 코드 작성 규칙을 따랐는지 등의 경험도 함께 언급하면 좋습니다.
Edit on GitHub
Last updated on