Чем отличаются 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 да нет нет
--- --- --- ---
Требуется инициализация нет нет да
--- --- --- ---
Замыкания в цикле нет да да
--- --- --- ---