Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке тимчасова мертва зона (TDZ) для let і const?

Змінні let, const (і класи) теж «піднімаються» на початок своєї області видимості, але не ініціалізуються. Від початку блоку до рядка оголошення змінна існує, але звертання до неї кидає ReferenceError. Цей проміжок називають тимчасовою мертвою зоною (temporal dead zone).

{
  console.log(price);   // ReferenceError: Cannot access 'price' before initialization
  let price = 100;
}

З var поведінка інша - змінна ініціалізується як undefined, і помилка тихо проходить:

console.log(total);   // undefined
var total = 100;

Чому це «тимчасова», а не «просторова» зона. Важливий момент виконання, а не позиція в тексті:

function showPrice() {
  console.log(price);   // функцію оголошено вище за let...
}
let price = 100;
showPrice();            // ...але викликано після ініціалізації - працює

Неочевидні випадки:

  • typeof не рятує. Для неоголошеної змінної typeof x повертає 'undefined', але для змінної в TDZ - кидає ReferenceError;
  • затінення:
const limit = 10;
function check() {
  console.log(limit);   // ReferenceError: внутрішня limit у TDZ
  const limit = 20;
}

Внутрішнє оголошення «закриває» зовнішнє для всього блоку, а не лише від свого рядка;

  • параметри за замовчуванням: function f(a = b, b = 1) {} - при виклику f() параметр b ще в TDZ;
  • класи: new User() до рядка class User {} теж кидає помилку, на відміну від функцій.

Навіщо це зроблено так:

  • помилка доступу до неініціалізованої змінної видна одразу, а не перетворюється на загадкове undefined;
  • const повинна мати рівно одне значення - побачити її «до» присвоєння було б порушенням цього правила.

Практичний висновок: оголошувати змінні до використання, на початку блоку чи безпосередньо перед ним. Помилки TDZ найчастіше трапляються при циклічних імпортах модулів: модуль звертається до експортованого const іншого модуля, який ще не встиг виконатися.

Докладніше в документації: let: тимчасова мертва зона

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання