Перейти к содержимому

Temporal Dead Zone (TDZ)

В одной фразе: TDZ — временная “мёртвая зона” для let, const и class, существующая с момента входа в блок до строки инициализации, где любое обращение к переменной бросает ReferenceError. На собесе важно объяснить: let тоже hoisted — просто не инициализирован.

{
// TDZ для x начинается при входе в блок ↑
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 10; // ← TDZ заканчивается здесь
console.log(x); // 10
}
// var для сравнения: нет TDZ, только undefined
{
console.log(y); // undefined (не ошибка)
var y = 10;
}
// typeof НЕ безопасен для переменных в TDZ (в отличие от необъявленных)
typeof undeclaredVar; // 'undefined' — безопасно для необъявленных переменных
// typeof x; // ReferenceError — если x объявлен через let/const в этом блоке!
let x = 1;
// TDZ в параметрах функции: инициализируются слева направо
function init(x = y, y = 2) {}
// init() → ReferenceError: y is in TDZ когда вычисляется дефолт для x
// Классическая ловушка: self-reference при инициализации
// const arr = [arr?.length ?? 0]; // ReferenceError: arr в TDZ!
// Правильно — объявить сначала, потом использовать:
const arr = [];
arr.push(arr.length); // теперь arr инициализирован
// TDZ в class fields (ES2022)
class Foo {
x = this.y + 1; // TDZ? Нет — поля инициализируются в порядке объявления
y = 10; // x = undefined + 1 = NaN (y ещё не инициализирован в момент x!)
}
new Foo(); // { x: NaN, y: 10 } — порядок важен!

Итог: TDZ делает let/const предсказуемее var, запрещая использование до объявления. Переменная “поднята” (зарегистрирована), но не инициализирована.