[기술면접] Hoisting, TDZ

한재창·2023년 3월 28일
0
post-thumbnail

Hoisting 이란? TDZ란?

프로그램은 작성한 코드의 순서에 따라 윗줄부터 차례로 실행되는데 변수 선언은 이 원칙을 따르지 않습니다. 호이스팅은 변수나 함수를 선언했을 때 스코프 내의 최상단으로 끌어 올려지는 것처럼 보이는 현상입니다.
TDZ(Temporal Dead Zone)는 일시적 사각지대로 선언 전에 변수를 사용하는 것을 비 허용하는 개념상의 공간입니다.

Hoisting

  • 호이스팅에 대해 간단히 요약해보자면 모든 선언들을 모두 끌어 올려서 해당 유효 범위(스코프)의 최상단에 선언하는 것을 의미한다.(이때 변수의 스코프에 따라 전역 스코프일 경우 스크립트 단위의 최상단으로 끌어올려지고, 함수 범위일 경우 함수 내 최상단으로 끌어 올려진다.)

  • 여기서 중요한 점은 선언된 것을 끌어올린다는 것과 선언과 할당된 값을 전부 끌어올리는 것이 아니라 선언만 끌어올려진다.

declaration(); // "선언식!"
expression(); // ReferenceError: Cannot access 'expression' before initialization

function declaration() {
  console.log("선언식!");
}

// 함수 표현식
const expression = function() {
  console.log("표현식!");
}
  • 하나의 예로 자바스크립트의 경우 함수를 생성할 때 선언, 표현 2가지 방식으로 함수를 생성할 수 있다.

  • 이때 선언으로 생성된 함수만이 끌어올려져서 호이스팅이 가능하다.

TDZ (Temporal Dead Zone)

  • 선언 단계부터 초기화 시작 전까지의 구간을 TDZ(Temporal Dead Zone)이라고 한다.

  • 자바스크립트에서 변수는 기본적으로 다음 3단계를 거쳐 생성이 된다.

  1. 선언 단계 (Declaration phase)
    변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미
    이 변수 객체는 스코프가 참조하는 대상이 된다.

  2. 초기화 단계 (Initialization phase)
    실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계
    이 단계에서 할당된 메모리에는 undefined로 초기화된다.

  3. 할당 단계 (Assignment phase)
    사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계

  • 실행 컨텍스트 : 코드가 실행되기 위해 필요한 환경
  • 스코프 : 변수가 값을 참조할 때 접근할 범위

var, let, 함수선억식

var

  1. 키워드 변수는 선언 시 선언과 초기화를 동시에 진행
  2. 자바스크립트는 실행 컨텍스트 변수 객체의 변수를 등록하고 메모리를 undefined로 만듦
  3. 변수에 값을 할당
  4. 변수는 값을 가지게 된다.

1, 2번 과정을 보면 선언과 동시에 초기화를 진행하며 메모리를 할당해주기 때문에 호이스팅이 될 때 참조가 가능해서 오류가 발생하지 않는 것이다!

let

let (+ const)의 경우 var와 달리 선언과 초기화를 따로 진행을 한다. 그렇기 때문에 선언단계에서 실행 컨텍스트에 변수를 등록했지만, 메모리가 할당되지 않아 접근할 수 없어서 ReferenceError가 발생한다. 즉 호이스팅은 되지만 접근할 수가 없어서 호이스팅이 되지 않는 것 처럼 보이는 것이다.

함수선언식

추가적으로 함수 선언식의 경우 선언, 초기화, 할당이 동시에 진행되기 때문에 호이스팅도 가능하고 실행도 가능하다.

정리

  • 호이스팅은 선언된 것들을 최상단으로 끌어올리는 행위를 말한다. 이때 변수에 어떤 값이 할당되기 전인 선언된 상태만 끌어올려진다. 그렇기 때문에 제일 처음의 예시 중 var로 선언과 할당을 했던 success는 호이스팅이 됐지만 undefined로 값이 나타났던 것이다.

  • 그리고 선언된 변수나 함수들을 최상단으로 끌어올려지는데 선언할 때 TDZ가 있는 즉, 스코프의 시작 지점부터 초기화 시작 지점까지의 구간이 있는 let의 경우(선언과 초기화가 따로 진행되는 경우), 호이스팅은 되지만 참조할 메모리가 없어 ReferenceError가 발생한다!

  • 호이스팅은 되지만 참조오류가 생기는 경우

    • let, const, class구문, class construtor()내부의 super()메소드 (상속받은 경우), 기본 매개변수(ES6)
  • 호이스팅도 되고 참조오류도 생기지 않는 경우

    • var, 함수 선언식, import
profile
취준 개발자

0개의 댓글