Способи оголосити змінну: var, let, const
У JavaScript є три способи оголосити змінну: var, let і const. Вони відрізняються областю видимості, можливістю перевизначення та поведінкою при спливанні (hoisting). Розберемо детально.
Теорія
TL;DR
var, функціональна область видимості, дозволяє повторне оголошення, спливає зі значеннямundefined.let, блокова область видимості, значення можна змінювати, повторно оголосити в тому самому блоці не можна.const, блокова область видимості, присвоїти нове значення не можна, але вміст об'єкта чи масиву змінювати можна.letіconstтеж спливають, проте до рядка оголошення перебувають у temporal dead zone і кидаютьReferenceError.- Сучасний стандарт:
constза замовчуванням,letза потреби,varне використовуємо.
Швидкий приклад
function demo() {
if (true) {
var fromVar = 'видно в усій функції';
let fromLet = 'видно лише в цьому блоці';
}
console.log(fromVar); // 'видно в усій функції'
console.log(fromLet); // ReferenceError: fromLet is not defined
}1. var, старий спосіб (ES5 і раніше)
var name = 'Tim';Особливості:
-
Можна перевизначати і перезаписувати:
javascriptvar x = 10; var x = 20; // не викликає помилки -
Функціональна область видимості (ігнорує блоки
{}):javascriptif (true) { var a = 5; } console.log(a); // 5, змінна «вирвалась» назовні блока -
Спливає (hoisting), тобто змінна доступна до оголошення, але значення
undefined:javascriptconsole.log(user); // undefined var user = 'Alex';
Використовувати
varу сучасному коді не рекомендується.
2. let, сучасний спосіб для змінюваних значень
let age = 25;
age = 26; // можна мінятиОсобливості:
-
Можна змінювати значення, але не можна повторно оголосити в тому самому блоці:
javascriptlet a = 1; // let a = 2; помилка SyntaxError -
Блокова область видимості:
javascriptif (true) { let x = 10; } console.log(x); // ReferenceError, змінна не видна за межами блока -
Недоступна до оголошення, на відміну від
var:javascriptconsole.log(a); // ReferenceError let a = 5;
Використовуйте
let, коли значення змінної буде змінюватись.
3. const, константа (незмінне посилання)
const PI = 3.14;Особливості:
-
Не можна перевизначити або оголосити повторно:
javascriptconst x = 10; x = 20; // TypeError -
Але якщо це об'єкт або масив, внутрішні дані міняти можна:
javascriptconst user = { name: 'Tim' }; user.name = 'Alex'; // можна // user = {} не можна, саме посилання перевизначити не вдасться -
Блокова область видимості, як у
let.
Використовуйте
constза замовчуванням, аletлише якщо змінна дійсно має змінюватись. Якщо потрібна справжня незмінність об'єкта, застосуйтеObject.freeze().
Спливання і temporal dead zone
Спливають усі три оголошення, різниця в тому, що відбувається до рядка оголошення. var ініціалізується значенням undefined ще на етапі створення області видимості, тому читання не падає, а мовчки повертає undefined, і це джерело важковловимих багів. let і const теж резервують ім'я, але лишають його неініціалізованим: проміжок від початку блока до рядка оголошення називають temporal dead zone (TDZ), і будь-яке звернення в ньому кидає ReferenceError.
console.log(withVar); // undefined, тихо і небезпечно
var withVar = 1;
console.log(withLet); // ReferenceError: Cannot access 'withLet' before initialization
let withLet = 1;Друга практична різниця видно в циклах: let створює нове зв'язування на кожній ітерації, а var одне на всю функцію.
for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 3 3 3
for (let j = 0; j < 3; j++) setTimeout(() => console.log(j)); // 0 1 2Коротке порівняння
| Особливість | var | let | const |
|---|---|---|---|
| Область видимості | Функціональна | Блокова | Блокова |
| Можна оголосити повторно | так | ні | ні |
| Можна змінити значення | так | так | ні |
| Спливання (hoisting) | Так, зі значенням undefined | Так, але не можна використати до оголошення | Так, але не можна використати до оголошення |
| Сучасний стандарт | Застарів | Так | Так |
Типові помилки
- Вважають, що
constробить об'єкт незмінним. Заморожене лише посилання:user.name = 'Alex'спрацює, а отuser = {}кинеTypeError. - Оголошують
constбез значення.const x;, цеSyntaxError, значення обов'язкове одразу. - Покладаються на спливання
varі читають змінну до оголошення, отримуючиundefinedзамість помилки. - Використовують
varу циклі з асинхронними колбеками і дивуються, чому всі колбеки бачать останнє значення лічильника. - Беруть
letтам, де значення ніколи не змінюється. Це приховує намір:constодразу повідомляє читачеві, що присвоєння більше не буде.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.