Чем 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 вызовет ошибку.