Чем var отличается от const


В JavaScript переменные могут быть объявлены тремя ключевыми словами: var, let и const. var — устаревший способ, используемый с самого начала языка, а const был введён в стандарте ECMAScript 6 (ES6) в 2015 году как средство объявления константных переменных, значение которых не может быть переназначено. Несмотря на это, const не делает значение неизменяемым, если это объект или массив.

Разница между var и const включает несколько ключевых аспектов: область видимости, поднятие, повторное объявление, переназначение, влияние на глобальный объект, поведение в циклах, свойства неизменяемости и предназначение.

1. Область видимости (Scope)

var — функциональная область видимости (function scope)

Переменные, объявленные через var, доступны во всей функции, в которой они объявлены, независимо от блока, в котором объявление происходит.

function example() {
if (true) {
var x = 10;
}
console.log(x); // 10
}

const — блочная область видимости (block scope)

Переменная, объявленная через const, доступна только в пределах блока {}, в котором была объявлена.

function example() {
if (true) {
const x = 10;
}
console.log(x); // ReferenceError: x is not defined
}

Таким образом, const предоставляет более строгую и локализованную область видимости, что предотвращает случайное использование переменных вне нужного контекста.

2. Поднятие (Hoisting)

var поднимается и инициализируется значением undefined

console.log(x); // undefined
var x = 5;

Это поведение может привести к неожиданным ошибкам, так как переменная существует до строки объявления, но с неопределённым значением.

const поднимается, но не инициализируется — возникает временная мёртвая зона (TDZ)

console.log(y); // ReferenceError
const y = 10;

JavaScript поднимает объявление, но доступ к переменной невозможен до фактического выполнения строки инициализации. Это поведение обеспечивает большую надёжность и помогает находить ошибки раньше.

3. Повторное объявление переменной

var позволяет повторно объявлять переменные в одной области видимости

var a = 1;
var a = 2; // допустимо, значение перезаписано

const не позволяет повторно объявлять переменные

const b = 3;
const b = 4; // SyntaxError: Identifier 'b' has already been declared

Это предотвращает непреднамеренное переопределение и повышает безопасность кода.

4. Переназначение значения

var допускает переназначение

var x = 5;
x = 10; // допустимо

const запрещает переназначение значения переменной

const y = 20;
y = 30; // TypeError: Assignment to constant variable

const означает, что переменная должна быть один раз инициализирована и далее не может быть переприсвоена.

5. Изменяемость объектов, объявленных через const

Несмотря на то, что const запрещает переназначение, это не делает содержимое объекта неизменяемым.

const obj = { name: "Alex" };
obj.name = "John"; // допустимо

Однако:

obj = { name: "Mike" }; // TypeError: Assignment to constant variable

Чтобы сделать объект действительно неизменяемым, нужно использовать Object.freeze():

const user = Object.freeze({ name: "Anna" });
user.name = "Kate"; // не изменится

То же касается массивов:

const arr = \[1, 2, 3\];
arr.push(4); // допустимо
arr\[0\] = 99; // допустимо
arr = \[9, 8, 7\]; // TypeError

6. Влияние на глобальный объект (в браузере — window)

var добавляет переменную к глобальному объекту, если объявлена глобально

var x = 100;
console.log(window.x); // 100

const не добавляет переменную к глобальному объекту

const y = 200;
console.log(window.y); // undefined

Это поведение делает const более безопасным для модульного и кроссбраузерного программирования, предотвращая загрязнение глобальной области.

7. Поведение в циклах

Одно из ключевых отличий проявляется при использовании переменных в циклах, особенно в асинхронном контексте.

for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 3, 3, 3

Переменная i создаётся один раз и продолжает существовать в каждой итерации.

for (const i = 0; i < 3; i++) {
// TypeError: Assignment to constant variable
}

Нельзя использовать const как счётчик в цикле for, если предполагается изменение значения.

Однако в for...of или forEach, где значение не перезаписывается, const работает корректно:

const arr = \[10, 20, 30\];
for (const val of arr) {
console.log(val); // 10, 20, 30
}

8. Поведение при удалении

var можно удалить из глобального объекта (если объявлен глобально):

var x = 1;
delete x; // true

const не может быть удалён:

const y = 2;
delete y; // false

9. Назначение и смысл

  • var предназначался для гибкой работы с переменными до появления блочной области видимости.

  • const предназначен для объявления переменных, которые не должны изменяться после инициализации, особенно в контексте:

    • константных значений (например, const PI = 3.14);

    • неизменяемых ссылок на функции, объекты и массивы;

    • предотвращения нежелательных изменений в коде.

10. Поддержка в старых браузерах

  • var поддерживается с самого начала языка.

  • const требует браузеров, поддерживающих ES6+:

    • полностью поддерживается во всех современных браузерах.

    • в старых (например, Internet Explorer до 11) может вызывать ошибки, если не использовать транспиляцию.

При использовании const в продакшн-коде принято применять транспиляторы, такие как Babel, чтобы преобразовать его в совместимый код.

11. Использование в функциональном программировании

Функциональный стиль программирования поощряет неизменяемость данных. const идеально подходит для этих целей:

const add = (a, b) => a + b;
const nums = \[1, 2, 3\];
const newNums = \[...nums, 4\]; // создаётся новый массив, старый не изменяется

Использование const помогает сделать код более предсказуемым, особенно в сложных структурах и потоках данных.

12. Поведение при деструктуризации

const можно использовать при деструктуризации объектов или массивов, если не планируется переназначать переменные:

const \[a, b\] = \[1, 2\];
const { name, age } = { name: "Eva", age: 30 };

При этом попытка переназначить a или name вызовет ошибку.