TDZ(Temporal Dead Zone)에 대해 알아봅시다.

LUCAS·2021년 6월 9일
4

왜 이 글을 쓰게 되었는가..

얼마 전에 기술 면접을 보게 되었다.
많은 기술 블로그를 보며 면접 관련 문서를 작성하였지만 면접관 분께서 TDZ를 설명하라는 말을 들었을 때 순간 잘못 알아 들었다고 착각할 만큼 생소한 단어였다.
Javascript 면접 질문 -1-
Javascript 면접 질문 -2-
Javascript 면접 질문 -3-
프론트엔드 개발자 면접 준비 (Javascript)
프론트엔드 개발자 면접 준비 (React)
정말 열심히 썼다..
이 많은 정리 글 중 어디에도 TDZ에 대한 언급은 없었다.

TDZ를 이해하면 좋은 이유

얼마전까지 나는 let/const가 호이스팅이 되지 않는다고 생각했다.

이유는 변수 초기화 시점 이전에 해당 변수를 참조하고자 하면 오류가 발생하는 것에 대해서 잘못 이해하고 있었기 때문이었다.

TDZ를 이해하면 실행 컨텍스트 변수 객체(VO)의 변수 객체화(Variable Instantiation)에 따른 어플리케이션의 실행 흐름을 보다 잘 이해할 수 있게된다.
(실행 컨텍스트는 여기에서(작성중) 알아보자)

예시 코드

먼저 TDZ가 발생하는 예시 코드를 보자

console.log(name);

const name = 'Lucas';

엄청 간단하다!

호이스팅을 이해하고 있는 개발자라면 위 코드는 어떻게 동작하고 있는지 금방 이해할 것이다.

식별자 name은 const 변수 생성 키워드를 통해 생성된 변수이다.

지금까지 나는 "const와 let은 변수 호이스팅이 되지 않아 변수 초기화 전에 참조할 시 오류가 발생하는 것"이라고 생각했다.

그렇다면 호이스팅은 되는데 왜 변수 참조는 안될까??

변수 객체화와 TDZ(Temporal Dead Zone)

이유를 설명하기 위해 실행 컨텍스트가 생성될 때 진행되는 변수 객체에 대한 변수 객체화를 설명한다.

변수 객체화는 자신의 실행컨텍스트(환경)에 해당하는 함수 내부의 변수와 내부 함수, 그리고 함수가 호출될 당시의 인자 및 인수를 객체 형태로 저장하는 것을 말한다. (형상화 개념)

예시를 들어보겠다.

function context (initialNumber) {
  var total = initialNumber;
	
  function getSum (sumNumber) {
    return total + sumNumber;
  }
  
  return {
    getSum,
  };
}

context(40);

위 context 함수는 컨트롤이 주어졌을 때 다음과 같은 형태의 변수 객체를 형상화한다.

// AO Structure
{
  initialNumber: 40,
  getSum: [Function],
  total: 40
}

여기서 우리가 보아야 할 것은 total 프로퍼티이다.
변수 객체화를 통해 함수 내부에 선언된 변수가 객체화될 때, 다음과 같은 단계를 거친다.

  1. 선언 단계 (Declaration phase)
    변수 객체에 등록하는 단계, 해당 변수 객체는 스코프가 참조할 수 있는 대상이 된다.
  2. 초기화 단계 (Initialization phase)
    선언 단계를 통해 선언된 변수 객체를 메모리에 할당한다. 할당 시 변수는 undefined로 초기화된다.
  3. 할당 단계 (Assignment phase)
    초기화 단계를 통해 초기화된 변수에 값을 할당한다.

이 것을 설명하는 이유는 다름이 아니라 다음을 설명하기 위해서이다.

  • var 키워드는 선언 단계와 초기화 단계가 동시에 이루어지지만 let과 const는 선언단계만 이루어진다.

자! 그럼 예시 그림을 보자.


설명한 그대로이다.
선언 단계와 초기화 단계가 동시에 일어나며, 이 때문에 변수 선언자 상단에서 변수를 참조하여도 오류가 발생하지 않는 것이다.

그럼 let과 const 는 어떨까?

  1. 실행 컨텍스트에 컨트롤이 주어졌을 때 선언 단계만 진행한다.
  2. let 변수 생성 키워드를 만나야 비로소 초기화 단계가 진행된다.
  3. 1번과 2번 사이에서 해당 변수에 접근하려 할 경우 오류가 발생한다. (throws ReferenceError)

위 과정 중 3번으로 인해 나는 그 동안 let과 const는 호이스팅이 되지 않는다고 착각했던 것이다.

그 동안 면접 질문에 대한 답변 중 "let과 const는 호이스팅이 되지 않기 때문에 선언부 상단에서 참조를 시도할 시 오류가 발생합니다!" 는 틀린 답변이었던 것이다. 자신있게 말하고다녀서 창피하다. 무튼...

3번에 해당하는 영역이 바로 TDZ(Temporal dead zone)이다.

정리

내가 여태까지 오해하고 잘못 알고 있었던 부분에 대해 다른 개발자들도 똑같은 경험을 했으리라 생각한다.
그래서 별도의 섹션을 나누어 정리하고자 한다.

모든 변수는 생성과 동시에 Javascript Parser를 통해 호이스팅된다!

그 동안 나는 변수 객체화 과정에서 초기화 단계가 이루어지지 않으면 해당 변수는 호이스팅이 되지 않는다고 생각했다.

하지만 TDZ를 이해하고 나니 나의 생각에서 무엇이 잘못 되었는지 알 수 있게 되었다.

var를 포함한 let/const 는 실행컨텍스트에 컨트롤이 주어졌을 때 변수객체화를 통해 선언단계가 진행되기 때문에 호이스팅이 된다고 생각해야한다.

즉, 모든 변수 생성 키워드는 호이스팅이 되나, 변수 객체화의 선언 키워드 별 변수 선언 단계 진행의 상이함으로 인해 참조가 불가능해 지는 것이다.

profile
안녕하세요! FE개발자 최근원입니다.

0개의 댓글