Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Область видимості (scope)». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Область видимості (scope) це механізм JavaScript, який визначає, де в коді доступні змінні та функції.** Глобальні змінні видно скрізь; змінні, оголошені всередині функції, видно лише в ній; `let` і `const` усередині блоку `{ }` живуть лише в цьому блоці, а `var` блочної області не має. Сам доступ визначається лексично, тобто місцем оголошення функції в коді, а не місцем її виклику. ```javascript if (true) { const x = 10; // блочна область var z = 30; // функціональна або глобальна } console.log(z); // 30 console.log(x); // ReferenceError ``` **Ключове:** scope визначається структурою коду на етапі написання, тому внутрішня функція завжди бачить змінні зовнішньої, але не навпаки.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Область видимості (scope) це механізм у JavaScript, який визначає, де в коді доступні змінні та функції**, тобто з яких частин програми до них можна звернутися. Scope задається структурою коду: кожна функція і кожен блок створюють власне оточення, вкладене в зовнішнє. ## Теорія ### TL;DR - Глобальна область: оголошення поза функціями та блоками, доступні будь-де в коді. - Функціональна область: змінні, оголошені всередині функції, доступні лише всередині неї. - Блочна область: `let` і `const` усередині `{ }` доступні тільки в межах цього блока. - `var` блочної області не має, він «випливає» до найближчої функції або в глобальний scope. - JavaScript використовує лексичну (статичну) область видимості: доступ визначає розташування функцій у коді, а не місце виклику. - Внутрішня функція запам'ятовує оточення, у якому була створена, це і є closure (замикання). ### Швидкий приклад ```javascript const appName = 'Notes'; // глобальна область function render() { const title = 'Hello'; // функціональна область if (title) { const suffix = '!'; // блочна область console.log(title + suffix + ' ' + appName); // Hello! Notes } console.log(suffix); // ReferenceError: suffix is not defined } render(); console.log(title); // ReferenceError: title is not defined ``` ### Глобальна область (Global Scope) Змінні, оголошені поза функціями або блоками, доступні **повсюди** в коді, зокрема всередині будь-якої функції. ```javascript let name = 'Tim'; // глобальна змінна function greet() { console.log('Hello, ' + name); // доступна тут } greet(); // Hello, Tim console.log(name); // доступна і тут ``` Глобальних змінних варто уникати: вони живуть увесь час роботи програми і будь-який модуль може їх перезаписати. ### Функціональна область (Function Scope) Змінні, оголошені за допомогою `var`, `let` або `const` **усередині функції**, доступні **тільки всередині цієї функції**. ```javascript function example() { let message = 'Inside function'; console.log(message); // працює } example(); console.log(message); // помилка: message is not defined ``` Кожен виклик функції створює нове оточення, тому локальні змінні різних викликів ніяк не перетинаються. ### Блочна область (Block Scope) Змінні, оголошені через `let` або `const` **усередині блока** `{ }` (тіло `if`, `for`, `while` чи просто пара дужок), доступні лише **в межах цього блока**. ```javascript if (true) { const x = 10; let y = 20; var z = 30; // var не має блочної області } console.log(z); // 30 (var видно за межами блока) console.log(x); // помилка: x is not defined console.log(y); // помилка: y is not defined ``` Саме через це `var` у циклі поводиться не так, як `let`: `var` створює одну змінну на всю функцію, а `let` нову на кожну ітерацію. ### Лексична область (Lexical Scope) JavaScript використовує **лексичну (статичну) область видимості**: доступ до змінних визначається **розташуванням функцій у коді**, а не тим, звідки їх викликають. ```javascript function outer() { const outerVar = 'I am outside'; function inner() { console.log(outerVar); // має доступ до outerVar } return inner; } const fn = outer(); fn(); // "I am outside" ``` > Тут `inner` запам'ятав оточення, у якому був створений, і це вже closure (замикання). Пошук змінної йде вгору ланцюжком областей: власна область, потім зовнішня, і так до глобальної. Якщо ніде не знайдено, отримуємо `ReferenceError`. ### Підсумок | Тип області видимості | Де створюється | Доступність | | --- | --- | --- | | **Глобальна** | Поза функціями та блоками | Скрізь | | **Функціональна** | Усередині функції | Тільки всередині функції | | **Блочна** | Усередині `{ }` (if, for тощо) | Тільки в межах блока | | **Лексична** | На етапі написання коду | Доступ до змінних зовнішніх областей | ### Типові помилки - Вважати, що `var` має блочну область. Він її не має, тому змінна «витікає» з `if` чи `for` у всю функцію. - Плутати лексичну область із динамічною: те, звідки функцію викликали, на видимість змінних не впливає взагалі. - Створювати змінну без оголошення (`count = 1`) і мимоволі отримувати глобальну; у строгому режимі це `ReferenceError`. - Звертатися до `let` чи `const` до рядка оголошення: змінна вже в області, але в temporal dead zone, і це `ReferenceError`. - Покладатися на глобальні змінні для передавання даних між модулями замість параметрів і повернених значень.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.