호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말한다.
자바스크립트의 모든 선언에는 호이스팅이 일어난다.
그런데 let, const, class를 이용한 선언문을 호이스팅이 발생하지 않는 것처럼 동작한다.
여기서 중요한 지점은 이 호이스팅이라는 용어가 ‘선언이 먼저 메모리에 저장되었다.’는 것을 의미하기 때문에 즉, ‘선언이 끌어올려진다’는 의미이기 때문에 모든 선언은 호이스팅이 일어난다는 말은 참이된다.
즉, 호이스팅이 파일의 맨 위로 끌어올려진 것 같은 현상을 의미할 때 선언문 이전에 참조해서 에러를 발생시킨다고 호이스팅이 일어나지 않은 것은 아니라는 의미이다.
왜냐하면 정말 선언은 끌어올려진 것이 맞다. (표현하면 그렇고 정확히는 선언이 코드 실행 전에 메모리에 저장되었다는 의미이다.)
JavaScript는 초기화를 제외한 선언만 호이스팅한다.
변수를 먼저 사용하고 그 후에 선언 및 초기화가 나타나면, 사용하는 시점의 변수는 기본 초기화 상태(var 선언 시 undefined, 그 외에는 초기화하지 않음)다.
-> var 키워드는 선언과 함께 undefined로 초기화되어 메모리에 저장되는데 let과 const는 초기화되지 않은 상태로 선언만 메모리에 저장되기 때문이다.
-> 초기화 되지 않으면 변수를 참조할 수 없다. 그래서 참조 에러를 일으키는 것이다.
-> let과 const에도 호이스팅이 일어나기 때문에 에러를 일으키는 것.(요것이 TDZ)
1단계: 선언 단계(Declaration phase)
2단계: 초기화 단계(Initialization phase)
3단계: 할당 단계(Assignment phase)
let 변수는 초기화하기 전에는 읽거나 쓸 수 없다.
변수 스코프의 맨 위에서 변수의 초기화 완료 시점까지의 변수는 "시간상 사각지대"(Temporal Dead Zone, TDZ)에 들어간 변수라고 표현한다.
TDZ 시맨틱은 선언 전에 변수에 접근하는 것을 금지한다. 변수 선언 전에 어떤 것도 사용하지 않는다.
TDZ는 const, let, class 구문의 유효성에 영향을 미치는 중요한 개념이다. TDZ는 선언 전에 변수를 사용하는 것을 허용하지 않는다.
반대로 var 변수는 선언 전에도 사용할 수 있기 때문에 var 사용은 피하는 것이 좋다.
TDZ는 언어 스펙에 맞도록 좋은 코딩 습관을 만들어주기 때문에 좋다고 생각한다.