[기술면접] 호이스팅과 Temporal Dead Zone

윤후·2022년 6월 20일
0

기술면접

목록 보기
3/28

호이스팅이란

  • 호이스팅은 코드를 실행하기 전 변수선언/함수선언을 해당 스코프의 최상단으로 끌어올리는게 아니다.
  • 호이스팅은 코드가 실행하기전 변수선언/함수선언이 스코프의 최상단으로 끌어올려진 것 같은 현상을 말한다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 가능한 코드를 형상화 하고 구분하는 과정을 거친다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 컨텍스트를 위한 모든 과정에서 모든 선언(const, let, var function, class)을 스코프에 등록한다.
  • 코드 실행전 이미 변수선언/함수선언이 저장되어 있기 때문에 선언문보다 참조/호풀이 먼저 나와도 오류 없이 동작하게 된다.
    (정확히는 var로 선언한 변수와 함수 선언문일 경우 오류없이 동작한다. 이는 선언이 파일의 맨위로 끌어올려진것 처럼 보이게한다.)

호이스팅이라는 용어를 js실행 컨텍스트에 의한 현상을 호이스팅이라고 부른다는 것으로 이해하면 되겠다. 선언이 코드 실행보다 먼저 메모리에 저장되는 과정으로 인한 현상이 일어나기 때문이다.

변수 호이스팅(const, var, let)

  • 자바스크립트의 모든 선언에는 호이스팅이 일어난다.
  • 그런데 let, const, class를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다.
  • var키워드로 선언된 변수와는 달리 let으로 선언된 변수를 선언문 이전에 참조하면 에러가 발생하게 된다.
  • 이는 let으로 선언된변수는 스코프의 시작에서 변수의 선언까지 Temporal Dead Zone에 빠지기 때문이다.

여기서 중요한 점은 이 호이스팅이라는 용어가 "선언이 먼저 메모리에 저장된다."는 것이다. 즉, "선언이 끌어 올려진다."는 의미이기 때문에 모든 선언은 호이스팅이 일어난다는 말은 참이 된다.

그렇다면 왜 TDZ가 일어나는 것일까?

var는 키워드 선언과 함께 undefined로 초기화 되어 메모리에 저장되는데 비해 let과 const는 초기화되지 않은 상태로 선언만 메모리에 저장되기 때문이다.

초기화 되지 않으면 변수를 참조할 수가 없기 때문에 참조 에러를 일으키는 것이다.

변수는 어떻게 생성되며 호이스팅은 어떻게 이뤄질까?

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

1단계 : 선언단계

  • 변수를 실행 컨텍스트의 변수 객체에 등록한다.
  • 이 변수 객체는 스코프가 참조하는 대상이 된다.

2단계 : 초기화 단계

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다.
  • 이 단계에서 변수는 undefined로 초기화 된다.

3단계 : 할당 단계

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

var로 선언한 변수는 선언 단계외 초기화 단계가 한번에 이뤄진다. 즉, 스코프에 변수를 등록하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화 한다. 따라서 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않는다. 다만 undefined를 반환하게 된다. 이후, 할당문에 도달하면 비로소 값이 할당된다.

let키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 스코프에 변수를 등록하지만 초기화 단계는 변수 선언문에 도달했을 때 이뤄지게 된다. 초기화 이전에 변수에 접근하려고 하면 참조에러가 발생하게 된다. 이는 아직 변수가 초기화 되지 않았기 때문이다. 즉, 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다. 따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다. 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 Temporal Dead Zone이라고 부른다.

호이스팅 예시

변수 선언에서의 호이스팅 예시

console.log(hi) // 선언 + 초기화 상태
var hi// 선언 + 초기화 상태 undefined 출력
hi = "hello" // 선언 + 초기화 + 할당 된 상태

호이스팅 때문에 선언이 끌어올려져 오류가 나지 않음.

console.log(hi) // 선언만 된 상태 초기화 되지 않아 참조가 불가능. 에러
let hi; // 여기서 초기화 단계가 실행

함수 선언에서의 호이스팅 예시

foo1(); // 함수 선언문에서는 호이스팅이 일어난다.
foo2(); // 함수 표현식에서는 호이스팅이 일어나지 않는다.

function foo1() {
  console.log('Hello');
}
var foo2 = function() {
  console.log('world');
}
profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글