
В JavaScript замыкание — это функция, позволяющая функции запоминать и получать доступ к переменным, которые не входят в ее непосредственную область действия.
Эта функция позволяет разработчикам создавать функции с закрытыми переменными, инкапсулировать логику и реализовывать обратные вызовы и обработчики событий.
Чтобы понять, как работают замыкания, давайте начнем с основ цепочки областей видимости в JavaScript.
В JavaScript каждая функция имеет свою область видимости, и переменные, объявленные внутри функции, не видны за ее пределами.
Однако функции могут обращаться к переменным, объявленным в своих родительских функциях, вплоть до глобальной области видимости.
Вот пример:
function outer() {
const a = 1;
function inner() {
const b = 2;
console.log(a + b); // Output: 3
}
inner();
}
outer();
В этом примере функция inner может получить доступ к переменной a, объявленной в функции outer, благодаря цепочке областей видимости. Однако после завершения выполнения функции outer переменная a становится недоступной.
Теперь давайте создадим замыкание:
function outer() {
const a = 1;
function inner() {
const b = 2;
console.log(a + b); // Output: 3
}
return inner;
}
const closure = outer();
closure(); // Output: 3
В этом примере функция outer возвращает функцию inner, которая затем присваивается переменной closure. Когда мы вызываем closure(), функция inner выполняется и все еще может получить доступ к переменной a, объявленной в функции outer, даже если функция outer уже завершила выполнение.
Замыкания полезны во многих сценариях, таких как создание закрытых переменных и методов, реализация каррирования и частичного применения, а также реализация обработчиков событий и обратных вызовов.
Вот пример того, как замыкания можно использовать для создания приватных переменных и методов:
function counter() {
let count = 0;
function increment() {
count++;
console.log(count);
}
function decrement() {
count--;
console.log(count);
}
return {
increment,
decrement,
};
}
const myCounter = counter();
myCounter.increment(); // Output: 1
myCounter.increment(); // Output: 2
myCounter.decrement(); // Output: 1
В этом примере функция counter возвращает объект с двумя методами, increment и decrement, которые имеют доступ к переменной count, объявленной в функции counter. Переменная count недоступна за пределами функции counter, что фактически делает ее частной.