[JavaScript] 호이스팅(Hoisting)이란?

박수현·2023년 4월 18일
0
post-thumbnail

이번 글에서는 아래 세 가지 내용에 대해 배워보도록 하겠다.

  • 자바스크립트에서 변수를 어떻게 생성하는지 이해한다.
  • let,const와 var 변수 선언에서의 호이스팅 예시를 이해한다.
  • 호이스팅이란 무엇인지 이해한다.

자바스크립트에서의 변수 생성 과정

1. 선언 단계 (Declaration phase)

  • 변수 객체를 생성하고 변수를 등록한다.
  • 스코프는 해당 변수 객체를 참조한다.

2. 초기화 단계 (Initialization phase)

  • 변수 객체에 등록된 변수를 메모리에 할당한다.
  • 변수는 undefined로 초기화된다.

3. 할당 단계 (Assignment phase)

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

아래 코드를 통해 각 단계가 어떻게 이루어지는지 살펴보겠다.


let, const에서의 변수 생성 과정 (feat. TDZ)

let: 선언과 초기화 단계가 분리되어 있어서 그 사이에 일시적으로 변수를 참조할 수 없는 구간인 TDZ가 존재하게 된다.

// 선언 단계
console.log(value); // TDZ

// 초기화 및 할당 단계
let value = "Hello World";

// ReferenceError: Cannot access 'name' before initialization

const: 선언과 초기화가 동시에 실행된다. 하지만 그 전에 TDZ가 생성되어 TDZ에 접근할 경우 Reference Error가 발생한다.

console.log(value); // TDZ

// 선언, 초기화, 할당 단계
let value = "Hello World";

// ReferenceError: Cannot access 'name' before initialization

TDZ(Temporal Dead Zone)란 스코프 또는 라이프 사이클의 시작 지점부터 초기화 단계 직전까지의 일시적 사각지대를 뜻한다.

var에서의 변수 생성 과정

var: 선언과 초기화 단계가 동시에 진행된다. 선언과 동시에 undefined로 초기화 되기 때문에 TDZ가 존재하지 않는다.

console.log(value); // 선언 및 초기화 단계

// 할당 단계
var value = "Hello World";

// undefined

호이스팅이란?

함수 안에 존재하는 모든 선언들을 해당 스코프의 최상단으로 끌어올리는 것

호이스팅은 크게 함수 선언 호이스팅과 변수 선언 호이스팅으로 나뉜다. 해당 개념에 대한 규칙을 요악하면 다음과 같은 항목으로 이루어진다.

  1. 선언된 함수는 상단에서 참조, 호출이 가능하다.
  2. 선언된 var는 상단에서 참조, 할당이 가능하다.
  3. 선언된 let const는 상단에서 참조, 할당이 불가능하다.

1. 함수 호이스팅

함수 호이스팅은 다른 무엇보다 가장 먼저 이루어진다. 게다가 선언, 초기화, 할당 단계를 동시에 진행하기 때문에 TDZ도 존재하지 않고 상단에서 참조, 호출이 가능하다.

2. 변수 호이스팅

  • var는 호이스팅이 발생하면, 선언과 초기화가 거의 동시에 이루어진다.실행 시점의 스코프 최상단에서 변수에 대한 메모리가 살아있기 때문에 선언부 위치에 상관없이 참조, 할당이 가능하다.

  • let, const는 호이스팅이 발생하면, 선언만 이루어지고 실행 시점에서 실직적인 선언부를 만날 때까지 초기화는 이루어지지 않는다. 이 간극만큼 해당 변수에 대한 메모리는 존재하지 않기 때문에 선언부 상단에서 참조, 할당이 불가능하다. 이 간극을 TDZ라고 부르며, 이 간극 때문에 호이스팅이 일어나지 않는 것처럼 동작한다.

글을 마치며

호이스팅은 JS의 특성에 따라 코드 실행 전에 컴파일 과정을 거치면서 자연스럽게 발생하는 전처리 과정이다. 호이스팅의 각 사례를 반복해서 읽고 비교해보면서 변수와 함수를 적절히 사용할 수 있도록 해야겠다.

profile
반갑습니다. 꾸준함과 글쓰기를 좋아하는 프론트엔드 개발자입니다. 블로그를 https://enjoydev.life로 이전했습니다 😀

0개의 댓글