변수나 함수의 호출 코드가 선언 코드보다 아래쪽에 있음에도 불구하고 에러가 발생하지 않고, 마치 선언 코드가 호출 코드보다 더 위에 선언된 것과 같이 동작하는 특성을 호이스팅(Hoisting) 이라고 한다.
자바스크립트에서 변수(variable)는 3가지 단계를 걸쳐 생성된다.
변수를 실행 컨텍스트의 변수 객체에 등록하는 단계이다.
이 변수 객체는 스코프가 참고하는 대상이 된다.
실행 컨텍스트에 존재하는 변수 객체에 선언 단계에서 생성된 변수를 위한 메모리를 만드는 단계이다.
이 단계에서 할당된 메모리에 undefined 를 할당한다.
초기화 단계에서 undefined로 초기화된 메모리에 다른 값을 할당하는 단계이다.
console.log(a); // undefined
var a = 3;
var를 이용하여 선언한 변수는 선언과 동시에 초기화 단계가 진행된다. 그러므로 자바스크립트 내부적으로 실행 콘텍스트의 변수 객채에 변수를 등록하는 동시에 메모리를 undefined로 만들어버린다. 그렇기 때문에 변수에 값이 할당되기 전에 호출해도 Reference 에러가 발생하지 않고, undefined가 리턴된다.
console.log(a); // ReferenceError: Cannot access 'greeting' before initialization
let a = 3;
console.log(a); // ReferenceError: Cannot access 'greeting' before initialization=
const a = 3;
반면 let, const를 이용하여 선언한 변수는 var와 다르게 선언 단계와 초기화 단계가 분리되어 진행된다. 실행 컨텍스트의 변수 객체에 변수를 등록했지만, 메모리에 할당되지 않아 접근할 수 없다. 그래서 Reference Error: Cannot access before initialization 에러 문구가 나오는 것이다. 즉, 호이스팅 되지 않는 것이 아니라, 호이스팅은 되었으나 메모리가 할당되지 않아 접근할 수 없는 것이다. 이때 등장하는 개념이 TDZ 이다.
한글로 직역하자면 일시적인 사각지대이다.
스코프 시작 지점 에서 초기화 시작 지점 까지를 TDZ(Temporal Dead Zone) 라고 한다.