Afaik

호이스팅(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;
  }
}

호이스팅 관련 모범 사례

호이스팅 모범 사례

  1. 변수는 사용하기 전에 선언하기
  2. const를 우선 사용하고, 필요시 let 사용
  3. var 사용 피하기 (함수 스코프와 호이스팅으로 인한 혼란 방지)
  4. 함수 선언문보다는 함수 표현식 사용 (명확한 실행 순서)

실무에서의 호이스팅 활용

// ❌ 나쁜 예시: 호이스팅에 의존
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