Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Способи оголосити змінну: var, let, const». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Оголосити змінну можна трьома способами: `var`, `let` і `const`, а різниця між ними, це область видимості, можливість перевизначення та поведінка при hoisting (спливанні).** `var` має функціональну область видимості та спливає зі значенням `undefined`; `let` і `const` мають блокову область видимості та до оголошення недоступні (temporal dead zone). За замовчуванням беріть `const`, а `let` лише тоді, коли значення справді має змінюватись. ```javascript const PI = 3.14; // не змінюється let age = 25; // змінюється var old = 'Tim'; // застарілий стиль, краще не використовувати ``` **Ключове:** `const` за замовчуванням, `let` за потреби, `var` не використовуємо в сучасному коді.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**У JavaScript є три способи оголосити змінну: `var`, `let` і `const`.** Вони відрізняються областю видимості, можливістю перевизначення та поведінкою при спливанні (hoisting). Розберемо детально. ## Теорія ### TL;DR - `var`, функціональна область видимості, дозволяє повторне оголошення, спливає зі значенням `undefined`. - `let`, блокова область видимості, значення можна змінювати, повторно оголосити в тому самому блоці не можна. - `const`, блокова область видимості, присвоїти нове значення не можна, але вміст об'єкта чи масиву змінювати можна. - `let` і `const` теж спливають, проте до рядка оголошення перебувають у temporal dead zone і кидають `ReferenceError`. - Сучасний стандарт: `const` за замовчуванням, `let` за потреби, `var` не використовуємо. ### Швидкий приклад ```javascript function demo() { if (true) { var fromVar = 'видно в усій функції'; let fromLet = 'видно лише в цьому блоці'; } console.log(fromVar); // 'видно в усій функції' console.log(fromLet); // ReferenceError: fromLet is not defined } ``` ### 1. `var`, старий спосіб (ES5 і раніше) ```javascript var name = 'Tim'; ``` Особливості: - Можна перевизначати і перезаписувати: ```javascript var x = 10; var x = 20; // не викликає помилки ``` - Функціональна область видимості (ігнорує блоки `{}`): ```javascript if (true) { var a = 5; } console.log(a); // 5, змінна «вирвалась» назовні блока ``` - Спливає (hoisting), тобто змінна доступна до оголошення, але значення `undefined`: ```javascript console.log(user); // undefined var user = 'Alex'; ``` > Використовувати `var` у сучасному коді не рекомендується. ### 2. `let`, сучасний спосіб для змінюваних значень ```javascript let age = 25; age = 26; // можна міняти ``` Особливості: - Можна змінювати значення, але не можна повторно оголосити в тому самому блоці: ```javascript let a = 1; // let a = 2; помилка SyntaxError ``` - Блокова область видимості: ```javascript if (true) { let x = 10; } console.log(x); // ReferenceError, змінна не видна за межами блока ``` - Недоступна до оголошення, на відміну від `var`: ```javascript console.log(a); // ReferenceError let a = 5; ``` > Використовуйте `let`, коли значення змінної буде змінюватись. ### 3. `const`, константа (незмінне посилання) ```javascript const PI = 3.14; ``` Особливості: - Не можна перевизначити або оголосити повторно: ```javascript const x = 10; x = 20; // TypeError ``` - Але якщо це об'єкт або масив, внутрішні дані міняти можна: ```javascript const 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`. ```javascript console.log(withVar); // undefined, тихо і небезпечно var withVar = 1; console.log(withLet); // ReferenceError: Cannot access 'withLet' before initialization let withLet = 1; ``` Друга практична різниця видно в циклах: `let` створює нове зв'язування на кожній ітерації, а `var` одне на всю функцію. ```javascript 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` одразу повідомляє читачеві, що присвоєння більше не буде.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.