본문 바로가기

[JavaScript] 호이스팅(Hosting)

by mugglim 2022. 7. 16.

호이스팅

호이스팅은 변수의 선언부와 함수의 선언문이 스코프의 최상단으로 끌어 올려지는 현상을 의미합니다. 스코프는 변수의 유효범위를 의미하며, 변수 선언 방식에 따라 다른 스코프를 가집니다. var은 function 스코프, let과 const는 block 스코프를 가지게 됩니다.

// (1) scope of x
var x;

{
    // scope of y
    let y;
    {
        // scope of z 
        let z;
    }
}

변수의 생성 과정

변수의 생성 과정은 선언 -> 초기화 -> 할당으로 3단계를 거칩니다. 위에서 살펴본 호이스팅은 변수의 선언 단계에 해당합니다. 단, var은 호이스팅 중 undefined로 초기화가 동시에 발생합니다. let과 const는 선언만 발생합니다.

TDZ(Temporal Dead Zone)

TDZ란 변수의 선언 단계에서 초기화 단계 까지의 영역을 의미합니다. 변수는 초기화 되기 전 까지 접근이 불가합니다. 그래서 TDZ에서 만약 변수를 접근하게 되면 에러가 발생하게 됩니다. TDZ를 테스트해보기 위해 간단한 예제를 확인해보겠습니다.

(1) var

var은 호이스팅 과정에서 선언과 초기화가 동시에 발생합니다. 그래서 var은 TDZ 영역이 없습니다. (엄밀히 말하자면 TDZ의 길이가 0입니다.

/* before hosting */
var x = 10;
console.log(x);
/* after hosting */
var x = undefined;  // (1) 선언 + 초기화

x = 10;               // (2) 초기화
console.log(x);      // 10;

(2) let, const

let과 const는 호이스팅 과정에서 선언만 발생합니다. 그래서 TDZ 영역이 존재합니다.

/* before hosting */
console.log(x);
let x = 10;
/* after hosting */
let x; // (1) 선언

// TDZ =====
console.log(x);  // ReferenceError: Cannot access 'x' before initialization
// ========

x = 10; // (2) 할당

(3) let은 호이스팅이 발생하지 않나요?

호이스팅을 검색해보면 "let과 const는 호이스팅이 발생하지 않는다"의 글을 종종 볼 수 있습니다. 하지만 이는 잘못된 개념입니다. let과 const는 block단위로 호이스팅이 발생합니다.

선언되지 않는 변수를 접근하면 ReferenceError: x is not defined 오류가 발생합니다.

// ReferenceError: x is not defined
console.log(x);

이와 달리, 선언 후 초기화 되지 않는 변수를 접근하면 ReferenceError: Cannot access 'x' before initialization 오류가 발생합니다.

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

만약 let x가 호이스팅 되지 않았다면 ReferenceError: x is not defined 오류가 발생해야합니다. 하지만 실제 에러는 ReferenceError: Cannot access 'x' before initialization입니다.

댓글