[JavaScript] 호이스팅(Hoisting)이란? 💬

혜혜·2024년 11월 4일
1

JavaScript

목록 보기
4/9
post-thumbnail

💡 핵심

📌 개요

인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스, import의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상

  • '보이는' 현상이라는 것이 중요. 실제로 끌어올리는 것이 아니다!
  • 인터프리터가 '변수'와 '함수'의 메모리 공간을 선언 전에 미리 할당하는 것

  • 자바스크립트 엔진은 코드를 실행하기 전에, 실행 가능한 코드를 구분하는 과정을 거침 (실행 컨텍스트)
  • 이때 모든 선언문(var, let, const, function, class)을 스코프에 등록
  • 그래서 코드 실행 전에 이 선언들이 다 저장되어 있기 때문에! 선언문보다 참조나 호출이 먼저 나와도 오류 없이 동작하는 것
  • 근데 변수냐 함수냐 class냐 import냐에 따라 조금씩 다르다
  • 그래서 자바스크립트의 모든 선언에서는 호이스팅이 일어나지만, let, const, class는 호이스팅이 일어나지 않는 것처럼 보이기도 함

  • ECMAScript 공식적으로 정의된 용어는 아님!
  • 구어체에서 대충 이런 의미로 통용될 수 있다
  1. 변수가 선언된 줄 이전에 해당 범위에서 변수 값을 사용할 수 있는 경우
  2. 변수가 선언된 줄 이전에 해당 범위의 변수를 참조할 수 있지만, ReferenceError를 던지지 않고 값이 항상 undefined인 경우
  3. 변수를 선언하면, 변수가 선언된 줄 앞의 범위에서 동작이 변경됨
  4. 선언의 사이드이펙트는, 선언이 포함된 나머지 코드를 평가하기 전에 발생함
  • var는 2번,
    let, const, class 선언은 3번,
    import는 1, 4번으로 호출됨

📌 함수 호이스팅

1. 함수 선언식

⭐ 전체 함수가 호이스팅 O

  • 함수 이름을 명시하여 함수를 정의하는 방식
greet(); // "Hello, World!"

function greet() {
  console.log("Hello, World!");
}

2. 함수 표현식

⭐ 변수만 호이스팅 되고, 함수 할당은 나중에 이루어짐!

  • 함수를 변수에 할당하는 방식
  • 함수 표현식의 호이스팅은, 변수 호이스팅처럼 동작
sayHello(); // TypeError: sayHello is not a function

const sayHello = function() {
  console.log("Hello, World!");
};

📌 변수 호이스팅

☑️ 변수 호이스팅 단계

  1. 선언 단계 (Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록
  2. 초기화 단계 (Initialization phase) : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보
  3. 할당 단계 (Assignment phase) : undefined로 초기화된 변수에 실제 값 할당

1. var

⭐ 선언과 동시에 undefined로 초기화가 이루어짐

  • 선언과 함께 undefined로 '초기화'되어 메모리에 저장되기 때문에, ReferenceError가 발생하지 않는다!
console.log(a); // undefined
var a = 10;
console.log(a); // 10

2. let

⭐ '선언'은 호이스팅되지만, TDZ로 인해 선언문 전에 접근 시 ReferenceError

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(b); // 20

3. const

⭐ '선언'은 호이스팅되지만, TDZ로 인해 선언문 전에 접근 시 ReferenceError

console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
console.log(c); // 30

☑️ TDZ(Temporal Dead Zone)

  • 변수의 '선언'과 변수의 '초기화' 사이 변수에 접근할 수 없는 지점
  • 스코프의 시작 지점부터 초기화 시작 지점까지의 구간

📌 import 호이스팅

⭐ 코드 실행 전에, 모듈이 로드됨

  • ESM의 정적 평가 : 모듈이 실행되기 전에 모든 import문을 분석하고, 모든 종속 모듈을 평가함
  • 그러기 위해서는 호이스팅이 되어야 한다 (결국 import문도 호이스팅이 된다)

📌 class 호이스팅

1. class 선언식

⭐ '선언'은 호이스팅이 되긴 하지만, '초기화'는 되지 않기 때문에 선언문 앞에서 사용할 수 없음

  • 호이스팅이 되지 않는 것처럼 동작
const personInstance = new Person("Alice"); // ReferenceError: Cannot access 'Person' before initialization

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}!`);
  }
}

2. class 표현식

⭐ 변수만 호이스팅 되고, 클래스 할당은 나중에 이루어짐

  • 함수의 표현식처럼 동작
const personInstance = new Person("Alice"); // ReferenceError: Cannot access 'Person' before initialization

const Person = class {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}!`);
  }
};

💡 참고 자료

profile
쉽게만살아가면재미없어빙고

0개의 댓글

관련 채용 정보