본문 바로가기

개발/Javascript

[Javascript] 호이스팅(Hoisting) 개념정리

 

최근 자바스크립트를 사용할 때 특정 개념들이 당연하게 여겨져 디테일하게 알아야 할 필요가 있다고 판단했습니다.

우선 호이스팅부터 정리해 보도록 하겠습니다.

 


호이스팅이란? 

호이스팅이란 자바스크립트 인터프리터가 코드를 실행하기 전 변수나 함수, 클래스 또는 임포트의 선언문을 해당 범위의 맨 위에서 선언이 된 것처럼 보이는 현상입니다.


 

자세히 살펴보면 다음과 같은 동작들을 호이스팅으로 간주할 수 있습니다.

 

1. 변수가 선언된 줄(line) 이전에 해당 범위에서 변수 값을 사용할 수 있는 경우

2. 변수가 선언된 줄(line) 이전에 해당 범위의 변수를 참조할 수 있지만 값이 항상 undefined 인 경우

3. 변수를 선언하면 변수가 선언된 줄(line) 앞의 범위에서 동작이 변경됨

4. 선언의 부작용은 선언이 포함된 나머지 코드를 평가하기 전에 발생함

 

 

우선 1번2번부터 살펴보겠습니다.

console.log(hoistingFunction, hoistingVariable);

function hoistingFunction() { }
var hoistingVariable = 123;

 

위의 코드를 보았을 때, 함수와 변수가 선언되기 전 console.log로 호출을 했기 때문에 당연히 오류가 나야 한다고 생각하지만 호이스팅 현상 때문에 오류가 나지 않고 함수와 변수가 출력되는 것을 확인할 수 있습니다.

ƒ hoistingFunction() {} undefined

 

 

여기서 function은 1번 (값 호이스팅) var는 2번 (선언 호이스팅)이 적용됩니다.

 

 

3번을 살펴보겠습니다.

console.log(hoistingVariable);

let hoistingVariable = 123;

 

let, const 및 class 선언은 호이스팅의 형태로 동작하지만 Temporal Dead Zone(TDZ)에 의해 제어됩니다.

이는 변수 선언이 코드의 최상단으로 올라가지만 실제로 값이 할당되기 전까지는 접근할 수 없는 것을 뜻합니다.

Uncaught ReferenceError: Cannot access 'hoistingVariable' before initialization

 

따라서 위의 코드를 실행시키면 let 변수는 실제로 선언되었지만 할당되기 전에 console.log로 호출하였으나 TDZ에 의해 제어되어 오류를 출력하게 됩니다.

 

 

마지막으로 4번을 살펴보겠습니다.

export let hoistingVariable = 123;
console.log(hoistingVariable)
import {hoistingVariable} from "./test.js";

 

import 선언은 늘 모듈의 최상단으로 호이스팅됩니다. 다른 점이 있다면 import는 전체 모듈의 최상단으로 이동하며, 어떤 코드도 실행되기 전에 먼저 처리됩니다. 이로 인해 import는 맨 위에서 선언하지만 위의 예제 코드에서는 출력을 위해서 일부러 밑에서 호출하였습니다.

123

 

import 선언을 호출 밑에서 하더라도 인터프리터는 모듈의 최상단에서 선언하기 때문에 잘 출력되는 것을 확인할 수 있습니다.

 


Reference

호이스팅 - MDN Web Docs