호이스팅

자바스크립트에서는 변수나 함수를 호출하는 코드를 먼저 작성하고 나중에 변수나 함수를 정의하는 코드를 작성해도 작동에 문제가 없는데, 이를 호이스팅(hoisting, 끌어올림)이라고 한다. 호이스팅은 ECMAScript 스펙에 정의된 용어가 아니며 다른 데에서도 호이스팅을 구체적으로 정의하고 있지는 않지만 이러한 동작을 설명하기 위해 널리 사용되고 있다.

sayHello(); // "Hello!"

function sayHello() {
  console.log("Hello!");
}

함수를 함수 선언식으로 작성하였을 때 함수는 스코프의 맨 위로 끌어올려진다. 한편, 함수를 함수 표현식으로 작성할 경우 함수를 선언하기보다 먼저 호출하려 하면 오류가 발생한다.

sayHello(); // TypeError: sayHello is not a function

var sayHello = function () {
  console.log("Hello!");
}

호이스팅이 일어날 때에는 선언만 먼저 동작하고 값의 대입은 원래 코드 위치가 실행될 때 이루어진다. 따라서 값이 대입되기 전에는 undefined인 상태이다.

for (var i = 0; i < 3; i++) {
  console.log(i);
}

console.log(i); // 3

for 반복문 안의 변수 ivar로 선언하여 사용한 위의 코드에서, 스코프에 따라 변수가 동작한다면 반복문 밖에서 i의 값을 출력하는 코드는 실행되지 못할 것이라고 예상할 수 있다. 하지만 i의 마지막 값인 3이 출력되었는데, 이는 내부적으로 i가 호이스팅된 것이다. 즉 i를 전역 변수로 먼저 선언하고 for 반복문 안에서 i의 값을 초기화하여 동작했기 때문이다. 따라서 실제로는 아래 코드가 실행된 것이다.

var i; // undefined
for (i = 0; i < 3; i++) {
  console.log(i);
}

console.log(i);

변수를 let이나 const로 선언해도 마찬가지로 변수가 호이스팅된다. 하지만 변수가 선언되고 초기화되는 사이에 let/const 변수에 접근하면 변수가 var 변수처럼 undefined를 반환하는 것이 아니라 오류(ReferenceError)를 반환하게 되어 있다. 이 오류가 반환되는 동안을 가리켜 변수가 Temporal Dead Zone(마찬가지로 ECMAScript 스펙상의 용어는 아니며, MDN에서는 "임시적인 사각 지역"이라고 옮기고 있다)에 있다고 한다.

results matching ""

    No results matching ""