JAVASCRIPT/BASIC

JS / Hoisting 호이스팅 개념 정리

24_bean 2022. 9. 22. 15:27

Hoisting : 호이스팅


Interpreter(javascript engine)가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것

 


많은 사람들이 호이스팅을

 

"코드를 실행하기 전 변수 및 함수 선언을 해당 스코프의 최상단으로 끌어올리는 것"


이라고 알고 있지만 해당 문장은 잘못된 이해이다.

정확히 하자면 다음과 같다.

 

"코드를 실행하기 전 변수 및 함수 선언을 해당 스코프의 최상단으로 끌어올리는 것처럼 보이는 것"

 

위에서 정의한 것 처럼 메모리 공간을 선언 전에 '미리' 할당하기 때문에 해당 스코프의 최상단으로 끌어올리는 것 처럼 보인다.

 


 

자바스크립트의 모든 선언에는 호이스팅이 발생하는데, 다음을 이용한 선언문은 호이스팅이 일어나지 않은 것 처럼 보인다.

 

  • let
  • const
  • class

예를 들어 다음과 같은 상황이 있다고 가정해보자

 

console.log(x);

var x = 1;

if (x === 1) {
  let x = 2;

  console.log(x);
  // expected output: 2
}

해당 경우는 var를 이용해 호이스팅을 보기위한 코드이다.

 

분명 실행했을 때 로그에 찍히는 결과는 다음과 같을 것이다.

> undefined
> 2

만약 var 선언을 let 선언으로 바꾸면 어떻게 될까?

console.log(x);

let x = 1;

if (x === 1) {
  let x = 2;

  console.log(x);
  // expected output: 2
}

해당 코드를 실행했을 때 로그는 다음과 같다.

Error: Cannot access 'x' before initialization

var과 달리 호이스팅 시 undefined로 변수를 초기화하지 않는다는 것을 알 수 있다.

따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외가 발생한다.

 

이때 생기는 문제를 '시간상 사각지대(Time Dead Zone: TDZ)라고 한다.

let 변수는 초기화하기 전에 읽거나 쓸 수 없는데, 초기화 전 접근하려고하면 ReferenceError가 발생한다.

 


결과적으로 호이스팅이 일어나면 어떤 점에서 이점을 보이냐면, 다음과 같은 코드가 실행될 수 있다는 점이다.

catName("Noah");

function catName(name) {
  console.log("Hello " + name + ", welcome!");
}

function의 선언이 호출보다 밑에 있지만 실행이 가능한 이유는 위에서 언급한 바와같이,

 

Interpreter(javascript engine)가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 호이스팅이 일어나기 때문이다.

 


references: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting