> Почему 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 для letconsole.log(a); // ReferenceError: Cannot access 'a' before initializationlet a = 5;// TDZ для constconsole.log(b); // ReferenceErrorconst b = 10;// var - без ошибки, но undefinedconsole.log(c); // undefinedvar c = 15;// typeof в TDZconsole.log(typeof d); // ReferenceErrorlet d = 20;// TDZ в блоке{console.log(x); // ReferenceErrorlet 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- у классов аналогичный механизм.
> Похожие задачи по frontend
Есть ли разница между вызовом setTimeout с нулевой задержкой и без тайминга в JavaScript
Какое преимущество промисов перед колбэками при работе с асинхронностью в JavaScript
Почему var всплывает и что происходит при всплытии в JavaScript
Как реализовать обработку клика на любой div внутри root и выводить в консоль только id этого div в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью