TDZ(Temporal Dead Zone)

TDZ에 대해 알려면, 호이스팅과 let, const, scope 등에 대한 기본적인 이해가 있어야 한다.

Temporal Dead Zone
위에서 이야기 한 것처럼 TDZ에 대해 알려면, 호이스팅, let & const에 대해 알아야 한다.
호이스팅
호이스팅은 인터프리터가 자바스크립트 코드를 해석함에 있어서 선언된 변수나 함수를 해당 Scope의 최상단으로 끌어올리는 것을 말한다.
let & const
let과 const는 ES5+부터 사용할 수 있는 변수타입이다.
let과 const는 var와 달리 block scope 기반으로 동작한다.
아래 코드를 보자.
                    
                        console.log(x);     // undefined
                        console.log(y);     // ReferenceError

                        var x = "x";
                        let y = "y";
                    
                
일반적인 호이스팅과 관련된 상식이면 변수 선언부는 해당 scope의 최상단으로 끌어올려져 해석된다.
(undefined는 참조는 했음. 하지만 변수에 할당된 값까지 호이스팅은 안되어서 undefined로 뜨는 것)
하지만 위 코드에서 let으로 선언한 변수 y는 ReferenceErro를 내뱉는다.

그럼 let은 호이스팅이 되지 않는 것인가?
그렇지 않다. let과 const 호이스팅의 영향을 받아 모두 스코프의 최상단에서 끌어올려진다.
block 스코프 기반이니 block의 최상단이라고 생각하면 된다.

위의 코드에서 let 변수에 접근이 불가능한 이유가 바로 TDZ 때문이다.
MDN 문서의 내용을 참고하자면, 아래와 같이 한마디로 정의할 수 있다.
let과 const는 블록의 시작부터 초기화가 실행되기전까지 TDZ에 존재하게 된다는 것.
TDZ에 존재하면 위와 같이 접근을 할 수 없다.
여러가지 상황들
                    
                        function test(){
                            var foo = 33;
                            if (true) {
                                let foo = (foo + 55); // ReferenceError
                                console.log(foo)
                            }
                        }
                        test();
                    
                
MDN에 있는 예제 소스이다.
함수 내부의 조건문 block의 소스에서, foo 참조시 TDZ로 인한 ReferenceError가 발생한다.
foo의 초기화 구문에서 (foo + 55)의 foo가 TDZ에 있기(아직 초기화가 되지 않았기) 때문이다.
                    
                        (function(a = b, b) {

                        }(undefined, 1)); // ReferenceError
                    
                
                    
                        (function(a = a) {

                        }()); // ReferenceError
                    
                
위의 2가지 예제들도 똑같이 에러가 발생한다.
함수의 디폴트 파라미터가 TDZ에 있는(초기화실행이 되지 않은 상태의) 값을 참조하고 있기 때문이다.
위의 경우에선, a가 b를 참조하는데, b의 초기화가 아직 되지 않은 상태이다.
(디폴트 파라미터는 왼쪽에서 오른쪽으로 실행)
아래에선, 위의 foo 예제와 같은 케이스이다. a의 초기화 구문에서 접근하려는 a가 TDZ에 있기 때문이다.
마치며
TDZ에 대해서는 헷갈릴 수 있을거라고 생각한다.(자바스크립트의 호이스팅때문에)
var로 변수를 선언하고 사용할 때도 마찬가지이지만, 초기화 후 사용에 대한 안전한 방식의 코딩스타일을 지향하는 것도 좋다.
확실한 것은, let과 const를 사용하고 TDZ에 대한 개념을 잘 알고 있다면, 여러 부작용을 방지할 수 있을것이다.