Что такое Temporal Dead Zone (TDZ) в JavaScript?

MiddleJavaScript · Frontend·Обновлено 26 июля 2026
Коротко
Temporal Dead Zone (TDZ) — это период между входом в область видимости и инициализацией переменной, объявленной через let или const, в течение которого обращение к ней вызывает ReferenceError.

Temporal Dead Zone (TDZ)

Temporal Dead Zone — «временная мёртвая зона» — это концепция, описывающая промежуток времени, в который переменная уже существует в области видимости (благодаря хоистингу), но ещё не инициализирована и недоступна для чтения или записи.

Как это работает

При входе в блок или функцию JavaScript-движок сначала сканирует все объявления переменных. Переменные var поднимаются и сразу инициализируются значением undefined. Переменные let и const тоже поднимаются, но не инициализируются — они находятся в TDZ вплоть до строки с объявлением. Попытка обратиться к ним до этой строки бросает ReferenceError.

console.log(a); // undefined — var поднята и инициализирована
var a = 5;

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;

TDZ в блочной области видимости

TDZ существует именно в блоке, в котором объявлена переменная, а не глобально. Это важно: даже если во внешней области есть переменная с тем же именем, внутри блока она недоступна до объявления.

let x = 'внешняя';

{
  // Здесь x попадает в TDZ — внешняя переменная «перекрыта»
  console.log(x); // ReferenceError, а не 'внешняя'
  let x = 'внутренняя';
  console.log(x); // 'внутренняя'
}

TDZ и параметры функции с дефолтными значениями

TDZ также применяется при вычислении дефолтных значений параметров. Параметры вычисляются слева направо, поэтому ссылка на следующий параметр вызовет ошибку.

// Некорректно — b ещё в TDZ при вычислении дефолта для a
function fn(a = b, b = 1) {
  return a + b;
}
fn(); // ReferenceError

// Корректно — a уже инициализирована
function fn2(a = 1, b = a) {
  return a + b;
}
fn2(); // 2

TDZ и typeof

Одно из важных отличий от var: оператор typeof для переменной в TDZ тоже бросает ReferenceError, тогда как для необъявленной переменной он вернул бы 'undefined'.

console.log(typeof undeclaredVar); // 'undefined' — нет ошибки
console.log(typeof tdzVar);        // ReferenceError
let tdzVar = 42;

Зачем TDZ нужна

TDZ — намеренное дизайн-решение для предотвращения ошибок. Использование переменной до её объявления почти всегда является ошибкой. TDZ делает такие ошибки явными и обнаруживаемыми немедленно, а не приводит к скрытому undefined, как это происходит с var.

Практические выводы

  • Всегда объявляйте let/const в начале блока, до первого использования.
  • TDZ — одна из причин предпочитать let/const над var: поведение более предсказуемо.
  • В классах TDZ применяется к полям, объявленным через declare или инициализаторам в теле класса до вызова super() в конструкторе наследника.

Что хочет услышать интервьюер

Кандидат объясняет, что TDZ — это период между хоистингом и инициализацией переменной

Понимает разницу в поведении var (инициализируется undefined) и let/const (остаются в TDZ)

Знает, что обращение к переменной в TDZ вызывает ReferenceError, а не возвращает undefined

Может привести конкретный пример кода с TDZ и объяснить, что произойдёт

Понимает, зачем TDZ введена — для предотвращения скрытых ошибок с использованием переменных до объявления

Пример: TDZ: примеры поведения let/const vs var

// TDZ для let и const
console.log(varVariable);   // undefined — var инициализирован сразу
// console.log(letVariable); // ReferenceError: Cannot access 'letVariable' before initialization

var varVariable = 'var';
let letVariable = 'let';

// TDZ в блоке — перекрытие внешней переменной
let value = 'внешняя';
{
  // console.log(value); // ReferenceError — внутренний let перекрывает внешний и находится в TDZ
  let value = 'внутренняя';
  console.log(value); // 'внутренняя'
}

// typeof и TDZ
console.log(typeof notDeclared); // 'undefined' — нет ошибки для необъявленной
// console.log(typeof tdz);      // ReferenceError — переменная в TDZ
let tdz = 1;

// TDZ в дефолтных параметрах функции
function bad(a = b, b = 2) { return a + b; }  // ReferenceError при вызове
function good(a = 1, b = a) { return a + b; } // 2 — всё корректно
console.log(good()); // 2

Типичные ошибки

Считают, что let/const вообще не хоистятся — на самом деле они хоистятся, но не инициализируются

Путают TDZ с обращением к необъявленной переменной и ожидают undefined вместо ReferenceError

Не знают, что typeof в TDZ бросает ошибку, в отличие от необъявленной переменной

Забывают о TDZ в блочных областях видимости при наличии одноимённой переменной во внешнем скоупе

Не могут объяснить практическую пользу TDZ — воспринимают её как странность, а не защитный механизм

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее