var, let и const — в чём разница? Block scope и TDZ
Почему var больше не пишут и что отвечать про block scope и TDZ.
Область видимости (scope) — часть кода, где переменная доступна.
varвидна во всей функции,let/const— только внутри блока{}.
Главные различия
| Свойство | var | let | const |
| Область видимости | функция | блок | блок |
| Переназначение | да | да | нет |
| Повторное объявление | да | нет | нет |
| До объявления | undefined | ошибка (TDZ) | ошибка (TDZ) |
Block scope: var «вытекает» из блока
var игнорирует фигурные скобки if и циклов — она привязана к функции. let и const ограничены блоком.
if (true) {
var a = 1;
let b = 2;
}
console.log(a); // var видна снаружи блока
try {
console.log(b); // let — нет
} catch (e) {
console.log(e.name);
}
Вывод:
1 ReferenceError
TDZ — временная мёртвая зона
let и const тоже «поднимаются» (об этом — следующий урок), но обратиться к ним до строки объявления нельзя — это и есть TDZ. У var такого нет: до объявления она просто undefined.
console.log(x); // var: уже существует, но без значения
var x = 5;
try {
console.log(y); // let: ещё в TDZ
let y = 10;
} catch (e) {
console.log(e.name);
}
Вывод:
undefined ReferenceError
const запрещает переназначение, но не мутацию
Важнейшая тонкость: const запрещает менять привязку переменной к значению. Если значение — объект, его внутренности менять можно.
const arr = [1, 2];
arr.push(3); // мутация — можно
console.log(arr);
try {
arr = [9]; // переназначение — нельзя
} catch (e) {
console.log(e.name);
}
Вывод:
[ 1, 2, 3 ] TypeError
Что отвечать про «какой выбрать»
Современная рекомендация, которую ждут на собеседовании: по умолчанию const, а let — только там, где переменную действительно нужно переназначать. var в новом коде не используют вовсе. Такой подход делает код предсказуемее: видя const, читатель сразу знает, что привязка не изменится. Если же спросят «а в чём именно опасность var?» — назовите две вещи: «утечку» из блока (переменная видна шире, чем ожидаешь) и тихий undefined при обращении до присваивания вместо явной ошибки.
Итог
var— функциональная область, «всплывает» какundefined; в новом коде не используется.let/const— блочная область и TDZ: до объявления обращение даёт ошибку.constзапрещает переназначение, но не мутацию содержимого объекта/массива.