호이스팅

호이스팅(Hoisting)

호이스팅이란, 코드에 선언된 변수 또는 함수가 코드 상단으로 끌어 올려진 것과 같은 현상이다.

끌어 올려지는 위치는 변수 또는 함수의 범위에 따라 달라진다.

함수 레벨 범위(Function Scope)의 변수는 해당 함수의 최상단으로 올라온다.

함수 레벨 범위를 벗어난 변수(전역 번수)는 스크립트의 최상위로 올라온다.

이 때, 변수가 호이스팅된다고 해서, 그 변수에 할당한 값까지 호이스팅되는 것은 아니다.

호이스팅되는 부분은 변수의 선언까지이다.

자바스크립트 엔진은 스크립트를 가져오면 코드를 먼저 훑는다.

코드는 실행되지 않고, 코드를 실행하기 위한 모든 함수와 변수의 선언(var, let, const, function)을 메모리에 저장한다.

코드가 실행되기 전에, 모든 선언은 메모리에 저장되어있다. 즉, 코드 상의 선언문보다 호출이 먼저 되어도(var , 함수 선언문의 경우) 오류가 발생하지 않는다.

var로 선언한 변수는 오류가 발생하지 않는다. 그리고 메모리에 undefined로 초기화되어 메모리에 저장된다.

let, const로 선언한 변수는 참조 에러가 발생한다. 오류가 발생했다고 해서, 호이스팅이 발생하지 않은 것은 아니다. 호이스팅은 정상적으로 일어났다. (코드가 실행되기 전에, 변수의 선언 메모리에 저장되어있다.)

오류가 나는 이유는, var로 선언한 변수는 undefined로 초기화되어 메모리에 저장되지만, let, const는 초기화되지 않은 상태로 메모리에 저장되기 때문이다.

초기화되지 않으면 변수 선언문 이전에 참조 또는 호출이 발생할 때, 이 변수를 참조할 수 없으므로 참조 에러가 발생하는 것이다.

즉, 변수의 호이스팅은 제대로 동작했다는 것이다.

스코프의 시작에서 변수의 선언 전 까지, 에러가 발생한 위와 같은 상황을 변수가 일시적 사각지대(Temporal Dead Zone, TDZ) 에 빠졌다고 말한다.

변수의 선언 과정

변수는 3단계에 걸쳐 생성된다.

1. 선언 단계(Declaration Phase)

  • 변수를 실행 컨텍스트(실행 가능한 코드가 실행되기 위해 필요한 환경)의 변수 객체에 등록됨
  • 이 변수 객체는 스코프가 참조하는 대상이 됨

2. 초기화 단계(Initialization Phase)

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보함
  • 변수는 undefined로 초기화됨

3. 할당 단계(Assignment Phase)

  • undefined로 초기화된 변수에 값을 할당한다.

var로 선언한 변수는 선언(1단계)과 초기화(2단계)가 함께 이뤄진다.

let로 선언한 변수는 선언(1단계)과 초기화(2단계)가 분리되어 진행된다.

스코프에 변수를 등록만하고, 초기화는 코드가 실행된 후, 아래로 내려가면서 변수 선언문에 도달했을 때 이뤄진다.

그렇기 때문에, 변수 선언문 이전에 변수에 접근하려할 때 참조 에러가 발생한 것이다.

스코프의 시작 지점부터 변수의 초기화 단계 이전까지 구간을 일시적 사각지대(TDZ) 라 부른다.

Reference

YUNSU BAE

YUNSU BAE

주니어 웹 개발자 배윤수 입니다!

예술의 영역을 동경하고 있어요. 🧑‍🎨