blog-imgDucklog

호이스팅이란 뭘까?

호이스팅

자바스크립트를 공부해 본 사람이라면 호이스팅이라는 단어를 무조건 들어봤을 것이다. 흔히 프론트엔드 신입 면접에서 100프로는 아니지만 정말 많이 물어보는 질문으로 호이스팅이 유명하다.


나도 개인적으로 호이스팅에 큰 관심은 없었지만, 면접을 준비하면서 호이스팅을 단순히 암기하기보다는 이해해야 면접 때 당황하지 않을 것 같아서 글을 쓰게 된다.

의미

호이스팅이란, 인터프리터가 변수와 함수의 메모리 공간을 선언하기 전에 미리 할당하는 것이다. 쉽게 이해하기 위해서 말하자면, 변수나 함수의 선언을 범위의 최상단으로 끌어올리는 것이다.

호이스팅을 이해하기 위해서는, 변수의 생성 단계를 알아야한다.


변수 생성단계는 아래와 같다.

  • 선언 단계

    변수 객체를 실행 컨텍스트에 등록한다.

  • 초기화 단계

    등록된 변수의 메모리를 확보하고 변수를 undefined로 초기화시킨다.

  • 할당 단계

    초기화된 변수에 실제 값을 할당한다.

let과 const는 위에 세 단계가 따로 따로 이루어지고


var은 선언단계와 초기화 단계가 한번에 이루어진다.


함수 선언문을 사용할 때는 세 단계가 한번에 이루어진다.

헷갈릴 수 있는 부분

let, const를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 작동한다.


var을 이용한 선언문과는 다르게 위 명령어로 이용하여 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생한다.


이는 let,const로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적 사각지대(TDZ)에 빠지기 때문이다.

그렇기 때문에 자바스크립트의 모든 선언에는 호이스팅이 발생한다!

예시

변수 선언문에서의 호이스팅

console.log(a);
a = 'hello';
var a;
console.log(a);

위 코드는 호이스팅으로 인해 선언문이 끌어올려져서 오류가 발생하지 않는다.


console.log(a); // 선언만 된 상태 (초기화가 아직 안됨)
let a; // 초기화 단계

위에 헷갈릴 수 있는 부분에서 설명한 것처럼 let은 var과 다르게 콘솔을 찍어보면 Reference 에러가 발생한다.


함수 선언에서의 호이스팅

duck1();
duck2();

function duck1() {
  console.log('hi');
}

var duck2 = function () {
  console.log('hi1');
};

duck1은 함수 선언문이기 때문에 호이스팅이 발생하지만, duck2는 함수 표현식이라서 호이스팅이 발생하지않아서 오류가 발생한다.