> Почему let и const выдают ошибку при обращении до объявления в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Сбер

Стек: JavaScript

> Пример ответа

Короткий ответ

let и const выдают ReferenceError при обращении до объявления из-за временной мёртвой зоны (Temporal Dead Zone, TDZ). Переменные поднимаются (hoisted), но не инициализируются - они находятся в неинициализированном состоянии с момента входа в область видимости до строки с объявлением. Любая попытка чтения или записи в этот период вызывает ошибку, в отличие от var, который инициализируется undefined.

Подробное объяснение

Механизм основан на спецификации ECMAScript. При входе в блок (scope) для let и const создаётся binding, но без initialisation - переменная существует, но её значение недоступно. TDZ начинается с начала области видимости и заканчивается в момент выполнения строки объявления. Доступ к переменной в этот период - ReferenceError. Это защита от использования неинициализированных значений и потенциальных багов.

var ведёт себя иначе: он поднимается и инициализируется undefined, поэтому ошибки не возникает, но значение до объявления - undefined, что часто приводит к неожиданному поведению.

typeof для переменной в TDZ тоже выбрасывает ReferenceError, в отличие от var, где typeof безопасен.

На практике

TDZ критична при циклических зависимостях в модулях или при использовании переменных до их объявления в функциях. Например, вызов функции, которая использует let-переменную до её объявления, приведёт к ошибке. Это делает код более предсказуемым и безопасным, особенно в больших проектах.

При рефакторинге с var на let/const нужно проверять порядок объявлений - код, который работал с undefined, может сломаться.

Пример кода

JAVASCRIPT
// TDZ для let
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;
// TDZ для const
console.log(b); // ReferenceError
const b = 10;
// var - без ошибки, но undefined
console.log(c); // undefined
var c = 15;
// typeof в TDZ
console.log(typeof d); // ReferenceError
let d = 20;
// TDZ в блоке
{
console.log(x); // ReferenceError
let x = 1;
}

Как отвечать на собеседовании

Начни с определения TDZ и её связи с hoisting. Объясни, что let/const поднимаются, но не инициализируются. Приведи контраст с var. Упомяни, что TDZ защищает от ошибок, связанных с использованием переменных до присваивания. Если спросят про typeof, укажи, что он тоже выбрасывает ошибку в TDZ. Будь готов обсудить практические последствия: циклические зависимости, порядок объявлений в функциях.

Что проверяет интервьюер

Понимание механизма hoisting и TDZ, различие между объявлением, инициализацией и присваиванием. Умение объяснить, почему это важно для безопасности кода. Способность провести аналогию с var и показать эволюцию языка. Знание спецификации ES6.

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

  • Утверждение, что let/const не поднимаются - на самом деле они поднимаются, но не инициализируются.
  • Путаница между hoisting и TDZ: hoisting - это подъём объявления, TDZ - период до инициализации.
  • Игнорирование того, что typeof тоже выбрасывает ошибку в TDZ.
  • Предположение, что TDZ работает только в глобальной области - она действует в любой области видимости (блок, функция).
  • Смешение TDZ с отсутствием hoisting у class - у классов аналогичный механизм.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью