Переменные JavaScript var, let и const (в чем отличие и когда использовать)?
Начиная с редакции Javascript ES6 у нас появилась возможность объявлять переменные с
помощью let
и const
, в дополнение к var
.
Давайте рассмотрим, чем они отличаются, и что лучше использовать.
Для начала, вспомним, как работает создание переменных с помощью var
.
В конце статьи будет ссылка на видео версию материала!
Переменные var
Можно Обновлять и Переопределять.
Давайте посмотрим, чему равно значение переменной amount
, которое мы получаем в логах console.log
:
1var amount = 100;2console.log(amount);3// получаем 10045amount = 200;6console.log(amount);7// получаем 200
В данном примере значение переменной amount
было обновлено значением 200.
Мы также можем добавить слово var
(случайно или намеренно) к переменной amount
и тем самым переопределить ее:
1var amount = 100;2console.log(amount);34// переопределяем переменную var5var amount = 200;6console.log(amount);
В логах отобразятся те же значения: 100 и 200. Проблема заключается в том, что мы не получим сообщения об ошибке, создавая вторую переменную с тем же названием в той же области видимости.
Область Видимости Переменной var
– Функция.
Это означает, что мы можем "изолировать" переменную var
, если создадим ее внутри какой-либо функции function(){}
.
В случае, если переменная var
создается за пределами функции – она доступна в глобальной области видимости, что может создавать проблемы.
Рассмотрим следующий пример.
Создадим переменную amount
внутри функции getAmount
и выведем в console.log
ее значение:
1function getAmount() {2 var amount = 100;3 console.log(amount);4 // получаем 1005}6getAmount();
В этом случае результатом console.log
будет значение нашей переменной amount
(100);
Что если мы выполним console.log
после вызова функции getAmount()
?
1function getAmount() {2 var amount = 100;3}4getAmount();5console.log(amount);6// ошибка ReferenceError
В этом случае мы получим сообщение об ошибке “amount is not defined”, так как переменная amount
находится внутри области видимости функции getAmount
.
Если нам понадобится значение переменной amount
в глобальной области видимости, нужно просто объявить ее за пределами нашей функции.
Соответственно внутри функции мы будем обновлять значение уже созданной переменной.
1var amount;2function getAmount() {3 amount = 100;4}5getAmount();6console.log(amount);7// получаем 100
Функции помогают нам упорядочить код и предотвратить “вытекание” переменных в глобальную область видимости.
Давайте рассмотрим еще один пример.
Запустите указанный код в консоли браузера:
1var weight = 500;2if (weight > 100) {3 var kilograms = weight;4 console.log(`Вес = ${kilograms}`);5 // Вес = 5006}
Здесь мы присваиваем значение переменной weight
переменной kilograms
, при условии, что значение weight
больше 100.
Переменная kilograms
находится внутри условия if
.
Теперь, если мы в консоли напишем название переменной kilograms
и нажмем enter – мы получим ее текущее значение,
которое ‘живет’ в глобальном объекте window
.
Проблема в том, что мы используем переменную kilograms
внутри нашего условия if
и не хотим делать ее доступной в глобальной области видимости.
Также, мы не используем функцию, которая могла бы изолировать ее от остального кода.
Здесь нам на помощь приходит ES6 с возможностью объявлять переменные с помощью let
и const
.
Как работают let и const?
В отличие от var
, область видимости let
и const
не функция, а блок {…}
, то есть сюда попадают как функции,
так и любые другие элементы с фигурными скобками.
Если в нашем примере объявить переменную kilograms
с помощью let
или const
, то она не будет доступна за пределами блока if (){…}
.
1var weight = 500;2if (weight > 100) {3 let kilograms = weight;4 console.log(`Вес = ${kilograms}`);5 // Вес = 5006}78console.log(kilograms);9// ошибка - ReferenceError
Отлично, благодаря использованию let
(либо const
), наша переменная kilograms
не “вытекает” в глобальный контекст!
Основное отличие let
от const
, это то, что переменные, созданные с помощью let
можно обновлять.
Как работает let?
Теперь давайте разберемся как создавать переменные с помощью let
.
Имеется следующий код:
1const car = 'tesla';2let speed = 60;3let fine = false;
Попробуем обновить значение speed
путем повторного декларирования:
1const car = 'tesla';2let speed = 60;3let fine = false;45let speed = 80;6// Ошибка
В консоли получаем ошибку о том, что переменная уже была объявлена ранее - 'speed' has already been declared
.
Почему это произошло? Потому что мы попытались повторно декларировать переменную с помощью let
,
которая находится в той же области видимости.
Вспомним, что в случае с var
, мы бы не получили сообщения об ошибке.
В результате была бы создана еще одна переменная с тем же названием, что потенциально могло привести к появлению ‘багов’ и ошибок.
Рассмотрим такой пример:
1const car = 'tesla';2let speed = 80;3let fine = false;45if (speed > 60) {6 let fine = true;7}89console.log(fine);10// false
Если мы выведем в console.log
переменную fine
, мы получим значение false
.
Мы не получаем сообщения об ошибке!
Причина заключается в том, что в этом примере у нас 2 разные переменные fine
.
Обе переменные находятся в разных областях видимости:
let fine = false
– глобальная область видимостиwindow
let fine = true
– внутри блокаif
Если мы создадим наши переменные с помощью var
, то в console.log
получим значение fine
равное true
.
Как Правильно Обновлять Переменные let ?
Обновление переменной, созданной с помощью let
происходит следующим образом:
1const car = 'tesla';2let speed = 60;3let fine = false;45speed = 100;
Если мы попытаемся таким же образом обновить переменную car
, то получим ошибку:
1const car = 'tesla';2let speed = 60;3let fine = false;45car = 'nissan';6// TypeError
Важно!
Некоторые начинающие разработчики ошибочно предполагают, что свойства объекта, созданного с помощью const
также нельзя обновлять.
Возьмем пример:
1const car = {2 name: 'Tesla',3 color: 'white',4};
Мы можем поменять любое из свойств объекта car
:
1car.name = 'nissan';2car.color = 'black';
Либо добавить новое свойство:
1car.age = 5;
Но если мы попытаемся повторно объявить саму переменную car
, то получим ошибку “ TypeError: Assignment to constant variable.”:
1const car = {2 name: 'Tesla',3 color: 'white',4};56car = {7 name: 'chevrolet',8};9// TypeError
Таким образом мы не сможем обновить переменную car
, присвоив ей новое значение.
В каких случаях использовать let, а в каких const?
Общее правило такое - если вам требуется переменная, значение которой будет обновляться – используйте let
, для всего остального – const
.
По умолчанию, я создаю все свои переменные с помощью const
. Если вижу, что переменную потребуется обновлять - меняю ее на let
.
Видео версия статьи доступна здесь: Видео версия