Чем отличаются var, let и const?
var, let и const — ключевые слова в JavaScript для объявления переменных. Они различаются по области видимости, всплытию (hoisting), возможности повторного объявления и изменяемости.
1. Область видимости (scope)
var: функциональная область видимости (function scope). Если переменная объявлена с var внутри функции, она доступна только внутри этой функции. Если вне функции — становится глобальной.
function test() {
if (true) {
var x = 10;
}
console.log(x); // 10 — переменная доступна вне блока
}
let, const: блочная область видимости (block scope). Переменные доступны только внутри блока {}.
function test() {
if (true) {
let y = 20;
const z = 30;
}
console.log(y); // ReferenceError
console.log(z); // ReferenceError
}
2. Всплытие (hoisting)
-
Все переменные (var, let, const) поднимаются (всплывают) вверх своей области видимости.
-
Но:
-
var инициализируется undefined при всплытии.
-
let и const не инициализируются. До явного объявления находятся в "временной мертвой зоне" (TDZ), что вызывает ReferenceError при обращении.
-
console.log(a); // undefined
var a = 5;
console.log(b); // ReferenceError
let b = 10;
3. Повторное объявление (re-declaration)
var: можно повторно объявить в той же области видимости. Это может привести к ошибкам и путанице.
var x = 1;
var x = 2; // допустимо
let и const: нельзя повторно объявить в одной и той же области.
<br/>let y = 1;
let y = 2; // SyntaxError
const z = 3;
const z = 4; // SyntaxError
4. Перезапись (изменяемость значения)
var: можно изменить значение.
var a = 1;
a = 2;
let: можно изменить значение.
<br/>let b = 1;
b = 2;
const: нельзя присвоить новое значение. Но если это объект или массив — можно менять внутреннее содержимое.
const c = 1;
c = 2; // TypeError
const arr = \[1, 2\];
arr.push(3); // допустимо
arr = \[4, 5\]; // TypeError
const obj = { key: 'value' };
obj.key = 'new'; // допустимо
obj = {}; // TypeError
5. Добавление в глобальный объект
При использовании var вне функции (в глобальной области) переменная добавляется как свойство к window (в браузере).
var a = 1;
console.log(window.a); // 1
let и const не добавляются в глобальный объект.
<br/>let b = 2;
console.log(window.b); // undefined
6. Использование в циклах
let и const создают отдельную переменную для каждой итерации цикла. Это важно в замыканиях.
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // 0 1 2
}
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // 3 3 3
}
7. const в контексте объекта
const означает, что переменная не может быть переназначена. Это не делает объект внутри "замороженным".
const obj = { a: 1 };
obj.a = 2; // можно
obj = { b: 3 }; // нельзя
Object.freeze(obj); // вот так можно "заморозить" содержимое
8. Инициализация
var: может быть объявлен без инициализации, значение будет undefined.
var x;
console.log(x); // undefined
let: может быть объявлен без инициализации, но нельзя использовать до объявления.
let y;
console.log(y); // undefined
const: обязательна инициализация при объявлении.
const z; // SyntaxError
9. Поведение в строгом режиме (strict mode)
-
Все переменные под let и const ведут себя так, как будто строгий режим уже включён.
-
var может вести себя "мягко" при отсутствии строгого режима.
10. Общее сравнение
Критерий | var | let | const |
---|---|---|---|
Область видимости | function | block | block |
--- | --- | --- | --- |
Всплытие | да, с undefined | да, но TDZ | да, но TDZ |
--- | --- | --- | --- |
Повторное объявление | разрешено | запрещено | запрещено |
--- | --- | --- | --- |
Перезапись | разрешено | разрешено | запрещено |
--- | --- | --- | --- |
Добавление в window | да | нет | нет |
--- | --- | --- | --- |
Требуется инициализация | нет | нет | да |
--- | --- | --- | --- |
Замыкания в цикле | нет | да | да |
--- | --- | --- | --- |