Переменные в JavaScript: var, let, const
Содержание
О проверке кода. Примеры не запускались — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Переменные — первое, что учат в JavaScript, и первое, где старые туториалы дают устаревший совет. Разберём три способа объявить переменную и когда какой.
Три ключевых слова
var a = 1; // старый способ, всплывает, виден во всей функции
let b = 2; // блочная область, можно переприсвоить
const c = 3; // блочная область, переприсвоить нельзя
Правило 2026 года короткое: const по умолчанию, let когда значение меняется, var — не используйте в новом коде.
Почему const по умолчанию, а не let? Потому что большинство переменных на самом деле не меняются, а const делает это явным: читатель сразу видит, что значение постоянно, и защищён от случайного переприсваивания.
Область видимости: главное отличие
function example() {
if (true) {
var x = 1; // виден во ВСЕЙ функции
let y = 2; // виден только в этом блоке { }
}
console.log(x); // 1 — работает
console.log(y); // ReferenceError — y не существует здесь
}
var игнорирует блоки — он виден во всей функции, где объявлен. let и const живут в своём блоке {} — в if, в цикле, в любых фигурных скобках.
Блочная область — не придирка, а то, что убирает целый класс ошибок. Самая известная:
// ❌ var: все три колбэка напечатают 3
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i)); // 3, 3, 3
}
// ✅ let: новая переменная на каждой итерации
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i)); // 0, 1, 2
}
С var переменная i — одна на весь цикл, и к моменту выполнения колбэков она уже равна 3. С let на каждой итерации создаётся новая i, и каждый колбэк запоминает своё значение. До появления let это лечили замыканиями и IIFE.
Hoisting: почему код видит переменную «заранее»
console.log(a); // undefined — не ошибка!
var a = 5;
console.log(b); // ReferenceError — «мёртвая зона»
let b = 5;
Hoisting (всплытие) — механизм, при котором объявления как будто поднимаются в начало области видимости. Но ведут себя var и let по-разному:
var всплывает со значением
Доступен до объявления
- Объявление поднимается наверх
- Значение —
undefinedдо присваивания - Обращение до строки — не ошибка, а
undefined - Источник скрытых багов
let / const — мёртвая зона
Ошибка до объявления
- Тоже всплывают, но без значения
- Обращение до строки →
ReferenceError - «Temporal Dead Zone»
- Ошибка честнее молчаливого
undefined
Поведение let здесь лучше: обращение к переменной до её объявления — это почти всегда ошибка, и ReferenceError честнее, чем молчаливый undefined, который потом всплывёт непонятным багом.
const не значит «неизменяемый»
Частое заблуждение:
const user = { name: 'Аня' };
user.name = 'Борис'; // ✅ работает — меняем СВОЙСТВО
user.age = 30; // ✅ работает — добавляем свойство
user = {}; // ❌ TypeError — переприсваиваем ПЕРЕМЕННУЮ
const защищает саму переменную, а не значение под ней. Переприсвоить user другому объекту нельзя, но менять содержимое объекта — можно сколько угодно. То же с массивами: const arr = [] не мешает arr.push(1).
Если нужна настоящая неизменяемость объекта — Object.freeze:
const config = Object.freeze({ port: 3000 });
config.port = 8080; // молча не сработает (в строгом режиме — ошибка)
Никогда без ключевого слова
function bad() {
leak = 5; // ❌ создаёт ГЛОБАЛЬНУЮ переменную!
}
Присваивание без const, let или var создаёт переменную в глобальной области — она видна отовсюду и живёт до конца программы. Это классический источник трудноуловимых багов, когда две функции неожиданно делят одну переменную. В строгом режиме такое просто запрещено и даёт ошибку — ещё одна причина, по которой модули (всегда строгие) безопаснее.
Правила именования
Короткие практические договорённости:
- camelCase для переменных и функций:
userName,getData; - UPPER_CASE для настоящих констант-значений:
MAX_SIZE,API_URL; - осмысленно, но не длинно:
userлучше, чемuи чемtheUserObjectFromDatabase; - начинать можно с буквы,
_или$; не с цифры; ключевые слова — нельзя.
Смежные темы: типы данных — что кладём в переменные; область видимости и hoisting — подробнее; ключевые слова — что нельзя называть. Полный список — в уроках JavaScript.