ДокументацияJavaScriptПеременные: var, let, const — отличия и когда использовать
Начальный 9 мин чтения

Переменные: var, let, const — отличия и когда использовать

Разбираемся чем отличаются var, let и const в JavaScript. Область видимости, всплытие, переназначение — с примерами и частыми ошибками.

varletconstпеременныепеременнаяобласть видимостиhoistingJavaScriptJS основы

Зачем нужны переменные

Переменная — это именованная ячейка памяти. Вы кладёте туда данные, чтобы использовать их позже:

let userName = 'Алексей'
console.log(userName) // Алексей

В JavaScript есть три ключевых слова для объявления переменных: var, let и const. Если вы начинаете изучать язык — важно понять разницу между ними, потому что они ведут себя совершенно по-разному.

const — объявляйте по умолчанию

const создаёт переменную, значение которой нельзя переназначить:

const PI = 3.14
PI = 3 // TypeError: Assignment to constant variable

Но «нельзя переназначить» не значит «нельзя изменить». Если внутри объект или массив — вы можете менять его содержимое:

const user = { name: 'Аня', age: 25 }
user.age = 26       // OK, свойство поменяли
user.city = 'Мск'   // OK, добавили свойство

const numbers = [1, 2, 3]
numbers.push(4)     // OK
numbers[0] = 99     // OK

user = {}            // TypeError — сама переменная не меняется

Отсюда правило: const не делает значение иммутабельным. Он запрещает присваивать новое значение самой переменной.

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

let — когда нужно переназначить

let позволяет менять значение:

let score = 0
score = 10    // OK
score += 5    // OK, score = 15

Типичные случаи — счётчики, промежуточные результаты, значения которые обновляются в цикле:

let result = null

for (const item of items) {
  if (item.active) {
    result = item
    break
  }
}

var — устаревший способ

var — это то, как объявляли переменные до ES6 (до 2015 года). Работает, но имеет пару неприятных сюрпризов.

1. Всплытие (hoisting)

Объявления var всплывают в начало области видимости. Кажется, что переменная существует до того, как вы её объявили:

console.log(name) // undefined, а не ошибка
var name = 'Борис'

JavaScript видит это так:

var name            // всплыло наверх, значение undefined
console.log(name)   // undefined
name = 'Борис'

Сравните с let и const — при обращении до объявления будет ошибка:

console.log(age)  // ReferenceError: Cannot access 'age' before initialization
let age = 30

Это полезное поведение. Лучше получить ошибку, чем молча работать с undefined.

2. Функциональная область видимости

var ограничен функцией, но не блоком. Блок — это всё между { }, например тело if, for, while.

if (true) {
  var x = 10
}
console.log(x) // 10 — x «утекла» за пределы if

С let и const такого не случится — они блочные:

if (true) {
  let y = 10
}
console.log(y) // ReferenceError: y is not defined

3. Классическая ошибка с циклом

Вот баг, который ловил каждый разработчик старой школы:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100)
}
// Вывод: 3, 3, 3

Три тройки вместо 0, 1, 2. Потому что var — одна переменная на всю функцию. К моменту срабатывания таймеров цикл уже завершился, и i равно 3.

С let каждый шаг цикла создаёт свою копию i:

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100)
}
// Вывод: 0, 1, 2

4. Повторное объявление

var позволяет объявить одну и ту же переменную дважды — без предупреждения:

var x = 5
var x = 10  // OK, молча перезаписано

let и const так не дадут:

let y = 5
let y = 10  // SyntaxError: Identifier 'y' has already been declared

Сводная таблица отличий

Свойствоvarletconst
Область видимостифункцияблокблок
Всплытие (hoisting)да, значение undefinedда, но «мёртвая зона»да, но «мёртвая зона»
Можно переназначитьдаданет
Повторное объявлениеданетнет
Использовать в 2025 годунетдада

Что такое «мёртвая временная зона» (TDZ)

Между началом блока и строкой объявления let/const переменная находится в Temporal Dead Zone. Она существует, но обращаться к ней нельзя:

{
  // здесь TDZ для name
  console.log(name) // ReferenceError
  let name = 'Оля'  // здесь TDZ заканчивается
}

Это защита от случайного обращения к переменной до её инициализации.

Можно ли объявить переменную без ключевого слова?

Технически — да. Но так делать никогда не следует:

city = 'Москва' // глобальная переменная (в браузере → window.city)

В строгом режиме это вызовет ошибку:

'use strict'
city = 'Москва' // ReferenceError: city is not defined

Всегда используйте let, const или var.

Практические правила

  1. По умолчанию — const. Если значение не нужно менять — const. Это 80% переменных в типичном коде.
  2. Нужно переназначить — let. Счётчики, аккумуляторы, промежуточные значения.
  3. var — не используйте. Он остался для обратной совместимости. В новом коде ему не место.
// Хороший стиль
const API_URL = 'https://api.example.com'
const MAX_RETRIES = 3
const users = ['Анна', 'Иван', 'Мария']

let currentUserIndex = 0
let hasError = false

for (let i = 0; i < users.length; i++) {
  // ...
}

Частые вопросы

Можно ли использовать const для объектов и массивов? Да. То что вы не можете переназначить переменную не мешает менять содержимое. Для настоящей иммутабельности используйте Object.freeze() или Object.assign() / spread для создания копий.

Что если я не знаю, будет ли переменная меняться? Начните с const. Если дальше по коду понадобится переназначить — поменяйте на let.

Почему в старых туториалах везде var? Потому что let и const появились в ES6 (2015 год). Материалы старше этого возраста используют только var.