что такое замыкание js
"Замыкание" - это способность функции запоминать переменные, которые были определены внутри родительской функции, даже после того, как родительская функция была выполнена.
Пример:
function createCounter() {
// переменная, которую нужно запомнить
let count = 0;
function counter() {
// увеличиваем нашу запомненную переменную
count++;
console.log(count);
}
// возвращаем функцию
return counter;
}
// создаем новую функцию (с замыканием)
const incrementCounter = createCounter();
incrementCounter(); // 1
incrementCounter(); // 2
incrementCounter(); // 3
В этом примере мы создали функцию createCounter()
, которая создает другую функцию counter()
. Внутри функции мы создали переменную count
, которая была определена внутри родительской функции. Функция counter()
возвращает значение count
, увеличивая его на 1
. Когда мы вызываем createCounter()
, она возвращает функцию counter()
, которая имеет доступ к count
благодаря замыканию. Каждый раз, когда мы вызываем incrementCounter()
,
Если мы создадим новый счетчик с помощью функции createCounter()
, то отсчет для него начнется заново.
// Создали еще одну новую функци-счетчик
const newIncrementCounter = createCounter();
newIncrementCounter(); // 1
newIncrementCounter(); // 2
newIncrementCounter(); // 3
Замыкание можно представить как способность функции "запоминать" и получать доступ к переменным из окружающего её лексического окружения, даже после завершения выполнения родительской функции. Проще говоря, функция "видит" и может использовать переменные, которые были доступны во время её создания.
Когда объявляется функция внутри другой функции, внутренняя функция формирует замыкание. Это замыкание предоставляет внутренней функции доступ к:
- Своим собственным переменным (локальные переменные).
- Переменным внешней функции.
- Глобальным переменным.
Пример:
const createPlayer = (initialScore) => {
let score = initialScore; // Приватная переменная, доступная только через замыкание
return {
getScore: function() {
return score;
},
addScore: function(amount) {
score += amount;
}
};
}
const player1 = createPlayer(100);
const player2 = createPlayer(50);
console.log(player1.getScore()); // 100
player1.addScore(50);
console.log(player1.getScore()); // 150
console.log(player2.getScore()); // 50
// Невозможно изменить "очки" напрямую:
player1.score = 10; // Error! "score" не доступен извне
console.log(player1.getScore()); // 150 (значение не изменилось)