← Назад к списку
ТехническаяFrontendJunior

В чём разница между var, let и const? Что такое всплытие (hoisting)?

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

  • var имеет функциональную область видимости, let и const — блочную
  • Объявления var всплывают со значением undefined
  • let и const до строки объявления находятся в TDZ
  • Обращение к ним до объявления даёт ReferenceError
  • const запрещает переприсваивание, но не мутацию объекта
  • var создаёт свойство глобального объекта, let и const — нет
  • В современном коде var практически не используют

let и const дают блочную область видимости и временную мёртвую зону, а var — устаревший механизм с функциональной областью и всплытием значения undefined.

Как сказать вслух

пример ответа

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

Подробный ответ

Основной ответ

Всплытие — это то, что движок при разборе кода регистрирует объявления до выполнения. Переменные var поднимаются в начало функции и сразу инициализируются значением undefined, поэтому обращение до объявления не падает, а молча возвращает undefined. let и const тоже регистрируются заранее, но не инициализируются: участок от начала блока до строки объявления называется временной мёртвой зоной (TDZ), и чтение там бросает ReferenceError. Область видимости var — функция целиком, let и const — ближайший блок в фигурных скобках, включая тело цикла: каждая итерация for с let получает свою привязку переменной, что решает классическую проблему замыканий в циклах. const фиксирует привязку, но не делает объект иммутабельным.

Ключевые моменты

  • Блочная область. let и const живут внутри ближайших фигурных скобок, var — внутри всей функции.
  • TDZ. До строки объявления let и const недоступны — это защита от использования неинициализированных переменных.
  • const и мутации. const запрещает только переприсваивание; свойства объекта и элементы массива менять можно, для заморозки есть Object.freeze.
  • let в циклах. Каждая итерация for с let создаёт отдельную переменную, поэтому колбэки в цикле видят правильное значение.

Практический контекст

Вопрос базовый, но по нему судят о понимании модели выполнения. Часто дают цикл с setTimeout и просят объяснить, почему с var выводится одно и то же число, а с let — разные. В рабочем коде это проявляется в линтерах (no-var, prefer-const) и в ревью: const по умолчанию делает код предсказуемее и сразу показывает читателю, что значение не переназначается.

Частые ошибки

  • Утверждают, что const делает объект неизменяемым
  • Говорят «let и const не всплывают» — всплывают, но без инициализации, отсюда TDZ
  • Не могут объяснить поведение var в цикле с асинхронным колбэком

ИП Кочкин Алексей Сергеевич · ИНН 390509026279 · ОГРНИП 325390000030973 · jiniys2005@yandex.ru