Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Глобальні змінні». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Глобальна змінна** - це змінна, доступна *всюди* в коді: у браузері вона зберігається в об'єкті `window`, у Node.js - у `global`. **Ключове:** глобальні змінні небезпечні через конфлікти імен, ускладнене налагодження і тестування, порушення інкапсуляції, витоки пам'яті та несумісність модулів і бібліотек.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке глобальні змінні > **Глобальна змінна** - це змінна, доступна *всюди* в коді. > > У браузері вона зберігається в об'єкті `window`, > у Node.js - у `global`. ```javascript var user = 'Tim'; // глобальна змінна console.log(window.user); // "Tim" ``` Глобальні змінні видно всім функціям, модулям і скриптам, і вони живуть до завершення роботи програми чи оновлення сторінки. --- ## Чому це **небезпечно** ### 1. Конфлікти імен (перезапис) Різні частини програми (або сторонні бібліотеки) можуть випадково використати те саме ім'я. ```javascript var config = { darkMode: true }; // десь у бібліотеці var config = { theme: 'light' }; console.log(config); // { theme: 'light' } ``` Ти не можеш "захистити" глобальну змінну - будь-яка частина коду може її змінити. --- ### 2. Важко налагоджувати і тестувати Коли змінна глобальна, неможливо зрозуміти: - хто її змінив; - коли вона змінилася; - хто від неї залежить. Це ускладнює логіку і робить баги **непередбачуваними**. ```javascript let counter = 0; function increase() { counter++; } function reset() { counter = 0; } increase(); reset(); // хтось викликав - і обнулив увесь стан ``` --- ### 3. Порушення інкапсуляції Глобальні змінні **ламають модульність**. Кожна частина програми знає про іншу - немає "ізольованого" коду. Це суперечить принципам **OOP** і **чистих функцій** (які не залежать від зовнішнього стану). --- ### 4. Витоки пам'яті Якщо глобальна змінна посилається на великий об'єкт, його **ніколи не видалить збирач сміття**, поки сторінка не перезавантажиться. ```javascript window.cache = new Array(1_000_000).fill('data'); // цей масив залишиться в пам'яті весь час ``` Тому що GC (Garbage Collector) не може видалити змінну, на яку є глобальне посилання. --- ### 5. Погана сумісність модулів і бібліотек Якщо ти використовуєш кілька бібліотек, а кожна визначає свої глобальні змінні, виникають "колізії просторів імен". ```javascript // бібліотека А window.$ = function(selector) { ... }; // бібліотека B window.$ = 42; ``` Браузер просто перезапише значення `$`, і весь твій код на jQuery перестане працювати. --- ### 6. Складніше рефакторити і повторно використовувати Якщо код залежить від глобальних змінних, його не можна просто "вирізати і вставити" в інший проєкт - він не буде працювати без усіх тих самих глобалок. --- ### 7. Проблеми з асинхронністю Асинхронний код (таймери, проміси, async/await) може звертатися до *однієї й тієї самої глобальної змінної* у різні моменти часу - і значення можуть бути неочікуваними. ```javascript let user = 'Tim'; setTimeout(() => console.log(user), 1000); user = 'Alice'; // через секунду: "Alice", а не "Tim" ``` Локальні змінні всередині функції захищають від таких ефектів. --- ## Як **уникнути** глобальних змінних ### 1. Використовувати `let` / `const` всередині функцій або блоків ```javascript function run() { const result = 42; console.log(result); } run(); console.log(result); // ReferenceError ``` --- ### 2. Використовувати модулі (ES Modules, CommonJS) Кожен модуль має **свою область видимості** і експортує тільки те, що явно вказано. ```javascript // utils.js export const sum = (a, b) => a + b; // main.js import { sum } from './utils.js'; ``` Тепер змінні всередині `utils.js` не "витікають" у глобальний контекст. --- ### 3. Використовувати об'єкти або простори імен Якщо потрібно зберігати спільні дані - тримай їх в об'єкті, а не в голій глобальній змінній. ```javascript const App = { config: { darkMode: true }, state: {}, init() { console.log('App started'); } }; App.init(); ``` Усе згруповано і не конфліктує з іншими бібліотеками. --- ### 4. Використовувати замикання (closures) Можна створити "приватний простір", недоступний зовні. ```javascript const counter = (function() { let value = 0; return { inc() { value++; }, get() { return value; } }; })(); counter.inc(); console.log(counter.get()); // 1 ``` Змінна `value` захищена і не "витекла" в глобальну область. --- ### 5. Використовувати `"use strict"` У строгому режимі JS **не дозволяє неявно створювати глобальні змінні**: ```javascript "use strict"; function test() { x = 10; // ReferenceError } ``` --- ## Підсумок | Проблема | Чому небезпечно | |---|---| | Конфлікти імен | Різні скрипти можуть перевизначати змінні | | Порушення модульності | Код перестає бути незалежним | | Витоки пам'яті | Змінні живуть до перезавантаження | | Складність тестування | Неможливо передбачити поточний стан | | Неявна поведінка | Складно зрозуміти, хто і коли змінює дані |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.