Область видимості (scope)
Область видимості (scope) це механізм у JavaScript, який визначає, де в коді доступні змінні та функції, тобто з яких частин програми до них можна звернутися. Scope задається структурою коду: кожна функція і кожен блок створюють власне оточення, вкладене в зовнішнє.
Теорія
TL;DR
- Глобальна область: оголошення поза функціями та блоками, доступні будь-де в коді.
- Функціональна область: змінні, оголошені всередині функції, доступні лише всередині неї.
- Блочна область:
letіconstусередині{ }доступні тільки в межах цього блока. varблочної області не має, він «випливає» до найближчої функції або в глобальний scope.- JavaScript використовує лексичну (статичну) область видимості: доступ визначає розташування функцій у коді, а не місце виклику.
- Внутрішня функція запам'ятовує оточення, у якому була створена, це і є closure (замикання).
Швидкий приклад
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)
Змінні, оголошені поза функціями або блоками, доступні повсюди в коді, зокрема всередині будь-якої функції.
let name = 'Tim'; // глобальна змінна
function greet() {
console.log('Hello, ' + name); // доступна тут
}
greet(); // Hello, Tim
console.log(name); // доступна і тутГлобальних змінних варто уникати: вони живуть увесь час роботи програми і будь-який модуль може їх перезаписати.
Функціональна область (Function Scope)
Змінні, оголошені за допомогою var, let або const усередині функції, доступні тільки всередині цієї функції.
function example() {
let message = 'Inside function';
console.log(message); // працює
}
example();
console.log(message); // помилка: message is not definedКожен виклик функції створює нове оточення, тому локальні змінні різних викликів ніяк не перетинаються.
Блочна область (Block Scope)
Змінні, оголошені через let або const усередині блока { } (тіло if, for, while чи просто пара дужок), доступні лише в межах цього блока.
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 використовує лексичну (статичну) область видимості: доступ до змінних визначається розташуванням функцій у коді, а не тим, звідки їх викликають.
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. - Покладатися на глобальні змінні для передавання даних між модулями замість параметрів і повернених значень.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.