Переменные — это база в любом языке программирования. Они нужны для того, чтобы хранить все данные во время работы программы. Обычно, чтобы использовать переменную в коде, сначала её нужно объявить, но в JavaScript это можно сделать с помощью трёх ключевых слов: var
, const
и let
.
Разберёмся, чем они различаются и в каких случаях что нужно использовать.
Немного теории
Объявление переменной — когда мы говорим программе: «Вот переменная, тут будут храниться данные».
Инициализация переменной — это когда мы записываем в объявленную переменную какие-то данные первый раз.
Область видимости переменной — та часть программы, где к этой переменной можно обратиться. Область видимости бывает двух видов:
- Функциональная: к переменной можно обращаться только внутри функции, где она была объявлена.
- Блочная: к переменной можно обращаться внутри блока кода, обозначенного фигурными скобками
{}
. Например, внутри циклов или условных операторов.
Подробно про область видимости можно почитать в нашей статье про замыкания.
Повторное объявление — когда мы пытаемся ещё раз объявить переменную, которая уже была объявлена раньше в текущей области видимости.
Переназначение — запись в переменную нового значения вместо старого, которое хранилось там раньше.
Поднятие (hoisting) — механизм в JS, который поднимает переменные и функции в начало своей области видимости перед выполнением кода. Это позволяет использовать переменные и функции до их фактического объявления в коде.
А теперь перейдём к делу.
Var
Ключевое слово var
появилось ещё в первых версиях JS, но сейчас от var
стараются отойти при написании кода. Почему так, сейчас объясним.
Обращение
Мы можем объявить переменную при помощи var и обратиться к ней, не присваивая ей значения:
var normal;
console.log(normal);
Значение такой переменной будет undefined
.
Мы также можем обращаться к переменной до её фактического объявления:
console.log(weird);
var weird = "Это поднятие";
Такой код не вызовет ошибки:
Это происходит потому, что переменная var
поднимается (hoisting) в текущей области видимости. Переменная уже была объявлена (поднята вверх), но её значение ещё не было присвоено, поэтому выводится undefined
.
Механизм поднятия применяется только к переменным, объявленным через var
. Чтобы избежать путаницы в коде, лучше объявлять переменные перед их использованием. Именно поэтому сейчас многие программисты переходят с var
на let
, чтобы не создавать таких ситуаций, когда переменной ещё фактически нет, но с ней уже что-то происходит.
Область видимости
Переменные, объявленные через var
, имеют функциональную область видимости. Это значит, что они доступны только в пределах текущей функции или глобального объекта, если функции нет.
Создадим функцию и внутри неё объявим переменную var
:
function example() {
if (true) {
var localVar = "Это локальная переменная";
console.log(localVar);
}
console.log(localVar);
}
example();
Мы объявили переменную localVar
внутри блока if
, но при этом она равно доступна внутри функции example
, поскольку var
не имеет блочной области видимости:
Мы получаем два значения, поскольку здесь также используется механизм поднятия. Через поднятие переменная «всплывает» вверх в пределах текущей области видимости (в нашем примере — до начала функции).
Переменная localVar
становится видимой во всей функции, а не только внутри блока if
, где была объявлена.
Переназначение и повторное объявление
Переменную, объявленную с помощью var
, можно переназначить в любом месте кода:
var x = 5;
console.log(x);
x = 10;
console.log(x);
Также var
можно заново объявить в текущем блоке. Причём количество объявлений числа может быть любым. Покажем переназначение на практике — переназначим переменную localVar
:
function example() {
if (true) {
var localVar = "Это локальная переменная";
var localVar = "Это другое значение переменной";
console.log(localVar);
}
console.log(localVar);
}
example();
Повторное объявление переменных считается плохой практикой, но бывают ситуации, когда оно нужно. Например, при работе с динамически загружаемыми модулями и при генерации кода на лету.
Let
Ключевое слово let
— это улучшенная версия var
. Оно было представлено в ES6 в 2015 году.
Обращение
Так же как и с var
, мы можем просто объявить переменную let
, не присвоив ей значение — это не вызовет ошибку:
let y
console.log(y)
Мы получим значение undefined
.
Но в отличие от var
, где используется механизм «поднятия», к переменной let
нельзя обращаться до момента объявления:
console.log(a)
var a = 5
console.log(с)
let c = 6
И если в случае var
мы получили undefined
, то у let
появилась ошибка: переменная не определена.
Область видимости
Переменные, объявленные с помощью let
, могут иметь глобальную, локальную или блочную область видимости.
Основное отличие let
— оно работает только в той области видимости, где объявлена.
Возьмём наш предыдущий пример и поменяем var
на let
:
function example() {
if (true) {
let localVar = "Это локальная переменная";
console.log(localVar);
}
console.log(localVar);
}
example();
Поскольку let
имеет блочную область видимости, то переменная localVar
будет видна только внутри блока if
.
Внутри блока мы успешно выводим значение переменной localVar
. А вот попытка вывести значение переменной вне этого блока сразу вызовет ошибку. Это более логичное поведение по сравнению с var
.
Переназначение и повторное объявление
Повторно объявить переменную let
в том же блоке кода нельзя:
let y = 20;
let y = 30
Код вызовет ошибку: переменная уже объявлена.
А вот переназначить переменную let
в том же блоке — можно.
let y = 20;
y = 50
Const
В JavaScript const
обладает всеми теми же свойствами, что и let
, за исключением того, что const
нельзя переназначить и что значение переменной должно быть присвоено сразу в момент объявления. Проще говоря, это константа, которую мы задаём один раз, и это значение больше не меняется, даже если попытаться это сделать.
Обращение
Значение const
должно быть сразу определено сразу при объявлении переменной. Нельзя обратиться к переменной до её инициализации.
Сравним его с let
и var
:
var d
console.log(d)
let e
console.log(e)
const i
console.log(i)
Область видимости
Здесь поведение const
такое же, как и у let
. Возьмём наш пример с функцией и убедимся в этом:
function example() {
if (true) {
const localVar = "Это локальная переменная";
console.log(localVar);
}
console.log(localVar);
}
example();
Область видимости переменной localVar
ограничивается блоком if
, где она объявлена. Поэтому обращение к ней вне этого блока вызовет ошибку:
Переназначение и повторное объявление
Значение const
нельзя ни переназначить, ни повторно объявить в текущей области видимости. Поэтому const
используется для создания постоянных переменных — констант.
const pi = 3.14159265358979323846
const pi = 3.15
Лайфхак: использование const
внутри циклов предотвратит ошибки изменения переменной внутри цикла.
Что и когда выбрать
Главное различие этих переменных — разная область видимости и возможность переназначения.
Используем var
, когда:
- нужно выйти за область видимости;
- пишем код для старых браузеров.
В остальных случаях почти всегда используется let
, чтобы избежать неожиданного поведения программы и странных ошибок.
А вот const
нужен для того, чтобы задать неизменяемую переменную — константу. Короче, если переменная будет меняться, то let
, а если не будет — то const