Замикання - це функція разом зі змінними того місця, де її створено. Внутрішня функція «пам'ятає» змінні зовнішньої навіть після того, як зовнішня вже завершилася.
function makeCounter() {
let count = 0;
return () => ++count;
}
const next = makeCounter();
next(); // 1
next(); // 2
// count недоступний ззовні, але живе, поки живе функція next
Де замикання трапляються щодня:
- Обробники подій і колбеки - вони бачать змінні з коду, що їх створив.
- Приватний стан - як
countвище: змінити його можна лише через функцію. - Фабрики функцій -
const add5 = makeAdder(5). - Хуки React - кожен рендер створює нові функції, що замикають значення стану саме цього рендеру.
Класична пастка з var у циклі:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i)); // 3, 3, 3
}
var має одну змінну на всю функцію, і до моменту спрацювання таймерів вона вже дорівнює 3. З let у кожної ітерації своя змінна, і виведеться 0, 1, 2.
Нюанс для пам'яті: поки замикання живе (наприклад, обробник не знято), живуть і всі змінні, які воно використовує, разом з великими об'єктами в них.