В чём разница между var, let, const?

JuniorJavaScript #javascript #variables

Вопрос

Чем отличаются var, let и const?

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

var — функциональная область видимости, поднимается (hoisting) с инициализацией undefined, можно переобъявлять. let/const — блочная область видимости, попадают в "temporal dead zone" до объявления. const дополнительно запрещает переприсваивание переменной.

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

  • Область видимости: var видна во всей функции, в которой объявлена (игнорирует блоки {}, if, for). let/const видны только внутри блока, в котором объявлены.
  • Hoisting (всплытие): все объявления поднимаются в начало области видимости на этапе компиляции, но ведут себя по-разному:
    • var поднимается и сразу инициализируется как undefined — обратиться к ней до строки объявления можно, получите undefined.
    • let/const тоже поднимаются, но попадают в temporal dead zone (TDZ) — обращение до объявления бросает ReferenceError.
  • Переобъявление: var можно объявить повторно в той же области видимости без ошибки. let/const — нельзя (SyntaxError).
  • Переприсваивание: var/let можно переприсваивать. const — нет, попытка бросит TypeError. Важно: const запрещает переприсваивание самой переменной, но не мутацию объекта/массива, на который она ссылается.

Пример

console.log(a) // undefined (hoisting)
var a = 1

console.log(b) // ReferenceError (TDZ)
let b = 2

const obj = { count: 0 }
obj.count++ // OK — мутируем объект, а не переприсваиваем переменную
obj.count = 5 // OK

obj = {} // TypeError: Assignment to constant variable

if (true) {
  var x = 'function-scoped'
  let y = 'block-scoped'
}
console.log(x) // 'function-scoped'
console.log(y) // ReferenceError: y is not defined

Дополнительные вопросы

  • Что такое temporal dead zone и зачем она нужна?
  • Почему в современном коде почти не используют var?
  • Можно ли изменить содержимое массива, объявленного через const?