[Javascript] Hoisting (호이스팅)

호이스팅이란

Hoist는 사전적으로 무거운 물건 및 무언가를 기계 등을 이용하여 위로 끌어 올리는 것(lift)을 의미합니다. 자바스크립트에서 호이스팅은 자바스크립트 Parser가 변수나 함수를 끌어 올려 최상단에 배치하는 것을 말합니다.

실제로 코드가 상단으로 올라가는 것은 아닙니다. 자바스크립트 Parser가 내부적으로 최상단에 끌어 올려서 처리하게 되며, 이 때 메모리 상의 변화는 없습니다.

호이스팅 대상

자바스크립트는 선언 구문만 호이스팅 합니다. 때문에 변수 선언 없이 먼저 변수를 사용하게 되더라도 예외가 발생하지 않습니다. 다만 그 변수는 사용되는 시점에 자동으로 기본 초기화 상태 (var 선언의 경우 undefined)가 됩니다.

자동으로 undefined 초기화가 되는 경우는 var 선언에만 해당됩니다.

아래의 코드를 실행하면 message에는 undefined가 출력됩니다.

1console.log(message);   // undefined 출력
2var message;            // 이 구문은 파서에 의해 호이스팅 됩니다.
3message = 'hoisting';   // 변수에 값 할당

하지만 선언 구문이 없으면 호이스팅이 발생하지 않기 때문에 변수를 읽을 때 예외가 발생합니다.

1console.log(message);   // ReferenceError 예외 발생
2message = 'hoisting';

호이스팅은 함수 선언에도 적용됩니다. 아래와 같이 함수를 먼저 호출하고 아래에 함수를 선언해도 파서에 의해 함수 선언은 상단으로 호이스팅 되기 때문에, 정상적으로 함수가 호출됩니다.

1showMessage('hoisting');
2            
3function showMessage(message) {
4  console.log("Message : " + message);
5}

호이스팅 시 예외 상황

let과 const

let과 const로 선언한 변수도 호이스팅 대상이지만, var와 달리 호이스팅 시 undefined로 변수가 초기화 되지는 않습니다. 때문에 변수 초기화 전에 변수를 읽으려고 하게 되면 예외가 발생됩니다.

함수 표현식

변수에 함수를 할당하는 형태인 함수 표현식은 호이스팅 되지 않습니다.

1showMessage('hoisting');    // Uncaught TypeError: showMessage is not a function 발생
2var showMessage = function(message) {
3  console.log("Message : " + message);
4}

아래는 Arrow function으로 함수 표현식을 작성한 코드입니다.

1showMessage('hoisting');    // Uncaught TypeError: showMessage is not a function 발생
2var showMessage = message => console.log("Message : " + message);