Замикання
Визначення простими словами
Замикання - це функція, яка "пам'ятає" змінні з області, де вона була створена, навіть якщо ця область уже завершила виконання.
Найпростіший приклад
javascript
function outer() {
let count = 0; // змінна зовнішньої функції
function inner() {
count++;
console.log(count);
}
return inner;
}
const counter = outer(); // викликаємо зовнішню функцію
counter(); // 1
counter(); // 2
counter(); // 3Що відбувається:
outer()виконується -> створює зміннуcountта внутрішню функціюinner.- Повертає
inner, яка пам'ятає, де була створена. - Навіть після завершення
outer(), зміннаcountне знищується, тому що на неї є посилання зinner.
Тобто:
javascript
outer() → створило count → inner() → запам'ятало countЗамикання = функція + оточення, в якому вона створена
Кожне замикання зберігає лексичне оточення (scope) - набір змінних, до яких воно має доступ.
Приклад:
javascript
function makeAdder(x) {
return function(y) {
return x + y; // доступ до "x" із зовнішнього скоупу
};
}
const add5 = makeAdder(5);
console.log(add5(10)); // 15
console.log(add5(7)); // 12Тут:
- Функція
makeAdderстворює і повертає нову функцію. - Повернута функція замикає значення
x(у нашому випадку5). - Навіть після завершення
makeAdder,xзалишається "живим".
Ще приклад - лічильник з приватною змінною
javascript
function createCounter() {
let count = 0;
return {
increment() { count++; },
decrement() { count--; },
get() { return count; }
};
}
const counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.get()); // 2Тут count недоступний ззовні напряму,
але доступний із замкнутих функцій (increment, get).
Це спосіб створювати приватні змінні в JavaScript.
Важлива властивість замикання
Функція пам'ятає не значення, а посилання на змінну у зовнішньому оточенні.
javascript
function make() {
let value = 1;
return () => console.log(value++);
}
const f = make();
f(); // 1
f(); // 2 ← змінна "value" жива між викликамиПоширена помилка (цикли)
javascript
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// через 1 секунду: 3, 3, 3Чому:
- Усі функції замкнули одну й ту саму змінну
i, і коли таймер спрацьовує -iвже дорівнює 3.
Виправлення через let (створює нову змінну на кожній ітерації):
javascript
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// 0, 1, 2Коротко запам'ятати
| Що це | Приклад |
|---|---|
| Функція, яка "пам'ятає" змінні з місця, де була створена | return function() { console.log(a); } |
| Змінні живуть, навіть якщо зовнішня функція вже завершилась | так |
| Створює приватні дані і стан | так |
| Часто використовується в колбеках, обробниках, модулях | так |
Аналогія
Замикання - це як рюкзак, у якому функція несе з собою всі потрібні змінні з місця, де народилась.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.