이전에 Temperal Dead Zone을 접해봤었지만 '이런거구나..'로 넘겨버린 탓에 정확하게 학습은 하지 못했었다.
SNS에 자바스크립트에 관련된 그리고 CS지식에 관련된 계정들을 팔로우해서 보는중에 TDZ에 대한 게시글을 보고 이번에 다시 확실하게 개념을 잡아보기로 했다.
ES6이전에 변수는 오직
var
로만 선언을 할 수 있었다.
하지만 ES6의 등장과 함께let
과const
가 새롭게 변수를 선언할 수 있는 방법으로 도입이 되었다.
let
과 const
는 블록스코프 개념으로 오직 { }
로 형성된 내부에서 접근이 가능하다.
function a() { // 함수 스코프 시작
for(let i = 0; i < 5; i++) { // 블록 스코프 시작
console.log(i);
} // 블록 스코프 종료
console.log('최종', i);
}; // 함수 스코프 종료
a();
/* 결과물
ReferenceError: i is not defined
*/
반면 var
는 함수스코프 개념으로 함수가 만들어진 곳이라면 어떤 다른 블록인 { }
가 있어도 접근이 가능하다.
function a() { // 함수 스코프 시작
// var로 변수를 선언했을 때
for(var i = 0; i < 5; i++) { // 블록 스코프 시작
console.log(i);
} // 블록 스코프 종료
console.log('최종', i);
}; // 함수 스코프 종료
a();
/* 결과물
0
1
2
3
4
최종 5
*/
함수 스코프와 블록 스코프는 말이 처음에는 무슨 차이가 있나 싶었는데 블록스코프가 더 큰 개념이라고 생각하니 이해가 잘 됐다.
var
로 선언하기 이전에 변수에 접근하게 된다면 undefined
를 도출하게 된다.
console.log(a); // undefined
var a = 5;
let
과 const
로 만약 위 처럼 선언 이전에 접근을 하게 된다면 Reference Error
를 도출하게 된다.
console.log(a); // Reference Error: a is not defined
let a = 5;
흔히 대부분이 hoisting
을 떠올릴 수 있는데 나도 마찬가지로 처음에는 "오? var
는 hoisting
이 되는거고 let
과 const
는 hoisting
이 안돼서 그러는거 아닌가?" 라고 생각을 했다.
var
는 hoisting
이 되어서 선언 이전에 콘솔을 찍어봐도 undefined
를 도출하는 것이고 let
과 const
는 hoisting
이 일어나지 않아서 참조에러를 도출해낸다고 생각했었다.
결론적으로는 이는 맞지 않았던 생각이었고 let
과 const
도 hoisting
이 된다. 하지만 hoisting
이 되는 과정에서 var
는 undefined
로 값을 초기화를 해버리는 것이고 let
과 const
는 초기화가 일어나지 않아 참조에러를 도출해내는 것이다.
여기서 Temporal Dead Zone의 개념이 등장한다.
TDZ는 변수에 도달할 수 없는 상태를 정의하는 용어로 이해할 수 있다.
즉, 스코프내에는 존재하나 선언되지 않은 것이다.
여기까지 봐왔다면 Temporal Dead Zone은 결국 let
과 const
에게만 해당하는 것으로 인식할 수 있다.
let
과 const
가 선언 이전에 그 값을 확인하려는 것은 TDZ가 있기 때문에 참조에러가 발생하고 var
는 그것과 상관없이 무조건 undefined
로 초기화 해버린다는 것을 알 수 있다.
// a라는 변수에 대한 Temporal Dead Zone의 시작
console.log(a);
let a = 5; // 여기에서 a의 Temporal Dead Zone이 끝난다.
// ReferenceError: a is not defined
console.log(a); // 위의 에러로 인해 스크립트는 애초에 첫번째 console.log에서 끝나버리고 5라는 값이 도출 되지 않는다.
if (true) {
// x 변수에 대한 TDZ의 시작
console.log(x); // x는 아직 TDZ에 있는 상태
// ReferenceError: Cannot access 'x' before initialization
let x = 50; // x의 TDZ가 여기서 종료 및 선언과 초기화가 이루어짐
}
기본적으로 let
이 호이스팅 되면 TDZ로 진입하고 초기화하고 선언 할 때마다 종료가 됀다. 따라서 처음에는 TDZ안에 있게되지만 선언하는 곳에 도달하게 되면 TDZ는 종료가 되는 것이다.
한 마디로 가장 잘 표현 할 수 있는 이유는 에러를 방지하는데 도움을 준다는 것
애초에 선언되지 않는 변수명에 접근 한다는 것 자체가 기본적으로 생각 할 때는 불가능 하다고 생각이 될 수 있다.
TDZ를 피하기 위해서는 변수를 선언하고 정의할 때 스코프의 최상단에서 이루어지는 것을 습관화 해야하는 것이 좋다.
Temporal Dead Zone을 풀어서 이해해보면 다음과 같이 이해 할 수 있다.
- Temporal : 일시적인 것
- Dead : 생명이 없는 상태
- Zone : 프로그래밍에서 메모리와 관련이 있는 곳
변수가 죽은 상태이거나 사용하지 못하는 곳에 머물러 있거나 변수가 생성되고 선언되는 그 사이의 시간대를 Temporal Dead Zone이라고 할 수 있다.