← Назад к вопросам

Почему объявление переменной через var устарело?

1.3 Junior🔥 221 комментариев
#JavaScript Core#React

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Эволюция объявления переменных: от var к let/const

Основная причина устаревания var — его архаичная и проблемная семантика, которая часто приводит к неочевидным багам и усложняет поддержку кода. Современные альтернативы — let и const — были введены в ES6 (2015) именно для решения фундаментальных недостатков var.

Ключевые проблемы var

1. Поднятие (hoisting) с неопределённым значением

Переменные var подвергаются hoisting'у, но инициализируются как undefined, что может вызывать неожиданное поведение:

console.log(x); // undefined, а не ReferenceError!
var x = 5;

В отличие от этого, let и const тоже подвергаются hoisting'у, но попадают в «временную мёртвую зону» (Temporal Dead Zone), где обращение к ним вызывает ошибку:

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;

2. Отсутствие блочной области видимости

var имеет только функциональную или глобальную область видимости, что особенно проблематично в циклах и условиях:

for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100); // Выведет 3, 3, 3
}
// Переменная i доступна и здесь: console.log(i) // 3

С let переменная ограничена блоком кода:

for (let j = 0; j < 3; j++) {
    setTimeout(() => console.log(j), 100); // Выведет 0, 1, 2
}
// console.log(j) // ReferenceError: j is not defined

3. Неявное создание глобальных переменных

При присвоении значения необъявленной переменной в нестрогом режиме создаётся глобальная переменная, что может приводить к конфликтам:

function example() {
    accidentalGlobal = 10; // Нежелательная глобальная переменная!
    var localVar = 5; // Локальная переменная
}

let и const предотвращают это, вызывая ошибку при попытке использования необъявленной переменной.

4. Множественное объявление без ошибок

Повторное объявление var в той же области видимости не вызывает ошибок, что может маскировать логические ошибки:

var user = "Alice";
// ... 100 строк кода ...
var user = "Bob"; // Без ошибки, возможно случайное переопределение

let и const предотвращают повторное объявление в той же области видимости:

let user = "Alice";
let user = "Bob"; // SyntaxError: Identifier 'user' has already been declared

5. Сложность предсказания поведения

Из-за сочетания hoisting'а, функциональной области видимости и возможности повторного объявления, код с var часто требует мысленного «перемещения» объявлений для понимания, что увеличивает когнитивную нагрузку.

Почему let и const стали стандартом

  • Явность и предсказуемость: let для изменяемых переменных, const для неизменяемых (хотя объекты, объявленные через const, остаются изменяемыми по содержимому).
  • Блочная область видимости: Естественно вписывается в современные паттерны программирования.
  • Защита от случайных ошибок: TDZ и запрет повторного объявления.
  • Лучшая оптимизация: Блочная область видимости даёт движку JavaScript больше возможностей для оптимизации.

Когда var ещё можно встретить

  1. Легаси-код: Старые проекты, библиотеки, написанные до ES6.
  2. Особые случаи: Иногда в Immediately Invoked Function Expressions (IIFE) для изоляции, но сейчас для этого используют блоки кода с let/const.
  3. Глобальные переменные в браузерах: Объявление в глобальной области видимости, но сейчас это считается антипаттерном.

Практический пример перехода

Старый подход с var:

var items = [];
for (var i = 0; i < 5; i++) {
    items.push(function() { return i; });
}
console.log(items.map(f => f())); // [5, 5, 5, 5, 5]

Современный подход с let:

const items = [];
for (let i = 0; i < 5; i++) {
    items.push(() => i);
}
console.log(items.map(f => f())); // [0, 1, 2, 3, 4]

Заключение

var устарел не потому, что он «сломан», а потому, что он был создан для более простой версии JavaScript. Современная разработка требует большей надёжности, предсказуемости и выразительности, которые обеспечивают let и const. Большинство линтеров (ESLint) по умолчанию запрещают использование var, рекомендуя const для неизменяемых значений и let для изменяемых. Это стало индустриальным стандартом, снижающим количество ошибок и улучшающим читаемость кода.

Почему объявление переменной через var устарело? | PrepBro