Переменные

Переменная — именованная область памяти для хранения данных, на которую можно ссылаться по имени.

Зачем нужно

Переменные позволяют сохранять значения и использовать их повторно. Без них каждое значение пришлось бы вычислять заново. Три ключевых слова — var, let, const — определяют, как переменная себя ведёт.

Где используется

Везде. Любая программа на JavaScript использует переменные для хранения данных, результатов вычислений, ссылок на DOM-элементы, настроек и состояния.

Предпосылки

Введение в JavaScript

var, let, const

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

var name = 'Алиса';
var name = 'Боб'; // Можно переобъявить — нет ошибки!
name = 'Чарли';   // Можно переназначить

// var имеет функциональную область видимости
function example() {
  var x = 10;
  if (true) {
    var x = 20;   // Та же переменная!
    console.log(x); // 20
  }
  console.log(x);   // 20 — значение изменилось
}

let (современный способ для изменяемых переменных)

let age = 25;
age = 26;           // Можно переназначить
// let age = 30;    // Ошибка! Нельзя переобъявить в той же области

// let имеет блочную область видимости
function example() {
  let x = 10;
  if (true) {
    let x = 20;   // Другая переменная!
    console.log(x); // 20
  }
  console.log(x);   // 10 — не изменилась
}

const (для неизменяемых привязок)

const PI = 3.14159;
// PI = 3;        // Ошибка! Нельзя переназначить
// const PI = 3;  // Ошибка! Нельзя переобъявить

// НО: объекты и массивы можно МУТИРОВАТЬ
const user = { name: 'Алиса' };
user.name = 'Боб';     // Можно! Меняем свойство, не привязку
user.age = 25;          // Можно! Добавляем свойство
// user = {};           // Ошибка! Нельзя переназначить

const colors = ['red'];
colors.push('blue');    // Можно! ['red', 'blue']
// colors = ;         // Ошибка!

Сравнительная таблица

Свойство var let const
Область видимости функция блок блок
Переобъявление да нет нет
Переназначение да да нет
Hoisting да (undefined) да (TDZ) да (TDZ)
Глобальное свойство window да нет нет

Hoisting (Всплытие)

JavaScript «поднимает» объявления переменных в начало их области видимости.

var hoisting

console.log(x); // undefined (не ошибка!)
var x = 5;
console.log(x); // 5

// Движок видит это так:
// var x;            // объявление поднялось
// console.log(x);   // undefined
// x = 5;            // присваивание осталось на месте
// console.log(x);   // 5

let/const и Temporal Dead Zone (TDZ)

// console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(y);    // 10

// TDZ — зона от начала блока до объявления
{
  // --- начало TDZ для z ---
  // console.log(z); // ReferenceError
  // --- конец TDZ ---
  const z = 'hello';
  console.log(z);    // 'hello'
}

Hoisting функций

// Функции поднимаются целиком
greet; // "Привет!" — работает до объявления

function greet() {
  console.log('Привет!');
}

// Но function expression НЕ поднимается
// sayBye; // TypeError: sayBye is not a function
const sayBye = function {
  console.log('Пока!');
};

Правила именования

// Допустимые имена
let userName = 'Алиса';     // camelCase — стандарт
let _private = true;         // подчёркивание в начале
let $element = null;         // доллар в начале (jQuery-стиль)
let имя = 'Кириллица';      // Unicode допустим, но не рекомендуется
let MAX_SIZE = 100;          // UPPER_SNAKE_CASE для констант

// Недопустимые имена
// let 2name = 'Боб';       // нельзя начинать с цифры
// let my-var = 5;           // дефис запрещён
// let let = 10;             // зарезервированные слова нельзя
// let class = 'A';          // тоже зарезервированное

Конвенции именования

// Переменные и функции — camelCase
let firstName = 'Иван';
function getUserName() { /* ... */ }

// Классы и конструкторы — PascalCase
class UserProfile { /* ... */ }

// Константы (известные до запуска) — UPPER_SNAKE_CASE
const API_URL = 'https://api.example.com';
const MAX_RETRIES = 3;

// Булевы переменные — с префиксом is/has/can/should
let isActive = true;
let hasPermission = false;
let canEdit = true;

Объявление нескольких переменных

// В одну строку (не рекомендуется)
let a = 1, b = 2, c = 3;

// Каждая на своей строке (рекомендуется)
let x = 10;
let y = 20;
let z = 30;

// Деструктуризация (удобно)
const { name, age } = user;
const [first, second] = [1, 2];

var и глобальный объект

// var создаёт свойство window (в браузере)
var globalVar = 'я в window';
console.log(window.globalVar); // 'я в window'

// let и const НЕ создают
let localVar = 'меня нет в window';
console.log(window.localVar);  // undefined

Частые ошибки

1. Использование var в циклах

// Проблема с var
for (var i = 0; i < 3; i++) {
  setTimeout( => console.log(i), 100);
}
// Выведет: 3, 3, 3 — все замыкания ссылаются на одну переменную

// Решение: let
for (let i = 0; i < 3; i++) {
  setTimeout( => console.log(i), 100);
}
// Выведет: 0, 1, 2 — каждая итерация имеет свою переменную

2. Мутация const объекта по ошибке

const config = { debug: false };
// Где-то в коде...
config.debug = true; // Компилятор не ругнётся!

// Решение: Object.freeze для полной неизменяемости
const frozenConfig = Object.freeze({ debug: false });
frozenConfig.debug = true; // Молча проигнорируется (в strict mode — ошибка)

3. Обращение до объявления

// Вместо получения undefined (var), получаем чёткую ошибку
// console.log(value); // ReferenceError
let value = 42;

Практика

  1. Объяви переменные name, age, isStudent с помощью const и let
  2. Попробуй переназначить const — убедись, что будет ошибка
  3. Создай объект с const и измени его свойство
  4. Напиши цикл с var и let внутри setTimeout — сравни результат
  5. Объяви переменную в if-блоке с let и попробуй обратиться к ней снаружи

Связанные темы

Ресурсы


🎓 Источник: 👶 JavaScript для начинающих 2. Имена, переменные, константы

  • 📅 2021-10-02 · YouTube
  • Тезисы: имена — это идентификаторы, отличие литералов от имён. Переменная связывает имя и значение. Константа — связывание без переназначения. Конвенции именования camelCase для переменных, UPPER_CASE для глобальных констант

⚡ Источник: JavaScript Беседы Идентификаторы · AsForJS

  • 📅 2023-10-21 · YouTube
  • Тезисы:
    • Identifier ≠ переменная. Идентификатор — это всегда ссылка (Reference) на запись в Environment Record
    • Все ошибки идентификаторов — ReferenceError, т.к. идентификатор — ссылка, не значение
    • "Передача по значению / по ссылке" в JS — упрощение. На уровне спеки всё — Reference

⚡ Источник: Українською про типи, змінні та хоістинг (з Дмитром) · AsForJS

  • 📅 2025-07-10 · YouTube
  • Тезисы: обзорная беседа о связях между типами, переменными и фазами выполнения, объясняющая почему let создаёт hole, а var связывается с undefined