Temporal Dead Zone과 Hoisting은 자바스크립의 필수적인 2개의 용어입니다. 하지만 이들을 제대로 이해하고 있지 않다면 이들이 어떻게 동작하는지는 쉽게 헷갈릴 수 있습니다.
TDZ(Temporal Dead Zone)은 컴퓨터가 값으로 완전히 초기화하는 순간까지 변수에 엑세스할 수 없는 블록 영역입니다.
초기화가 완료되기 전에 변수에 엑세스하려고 한다고 가정합니다. 이러한 경우 JavaScript는 ReferenceError
가 발생합니다.
따라서 JavaScript에서 이러한 오류가 발생하지 않도록 하여면 TDZ외부에서 변수에 접근해야 한다는 것을 명심해야 합니다.
그렇다면 TDZ의 시작과 끝은 정확히 어디일까요?
블록의 TDZ는 블록의 로컬 스코프 시작부분에서 시작됩니다. 그리고 그 끝은 변수가 값으로 완전히 초기화되었을 때입니다.
(A block's TDZ starts at the beginning of the block's local scope. It ends when the computer fully initializes your variable with a value.)
TDZ에 영향을 받는 구문은 크게
var로 선언된 변수는 선언과 초기화를 동시에 진행합니다. 그렇기 때문에 TDZ가 존재하지 않습니다.
let은 선언과 초기화가 분리되어 그 사이에 TDZ가 생성되고, const는 선언과 초기화가 동시에 진행되지만 선언 이전에 TDZ가 생성되어 접근하면 ReferenceError가 발생합니다.
함수 선언식은 선언, 초기화, 할당을 동시에 진행합니다.
class 구문도 선언 전에는 class를 사용할 수 없습니다.
// Does not work!
const myMezzo = new Company(7) // throws 'ReferenceError'
class Company {
constructor(color) {
this.color = color
}
}
위의 코드에서는 TDZ에 접근했기 때문에 Reference Error 가 발생합니다.
TDZ에 접근하지 않게 하기 위해서는 코드를 아래와 같이 바꿔야 합니다.
class Company {
constructor(color) {
this.color = color
}
}
// Works!
const myMezzo = new Company(7) // throws 'ReferenceError'
다음으로 constructor() 내부의 super() 메소드를 살펴봅시다!
부모 클래스를 상속받은 경우,
class MuscleCar extends Car {
constructor(color, power) {
this.power = power; // Access to TDZ
super(color);
}
}
// Does not work!
const myCar = new MuscleCar(‘blue’, ‘300HP’); // `ReferenceError`
constructor() 즉 생성자 안에서 super()가 호출되기 전까지는 this
바인딩은 TDZ에 있습니다.
TDZ는 인스턴스를 초기화하기 위해서는 부모클래스의 생성자를 호출한 뒤 this값을 사용하도록 유도합니다.
따라서 부모 클래스의 생성자를 호출한 뒤에 자식 클래스에서 this 값을 변경할 수 있습니다.
class MuscleCar extends Car {
constructor(color, power) {
super(color)
this.power = power
}
}
// Works!
const myCar = new MuscleCar('blue', '300HP')
myCar.power // => '300HP'
참조
https://www.freecodecamp.org/news/javascript-temporal-dead-zone-and-hoisting-explained/
https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/