Skip to main content

Замыкание (closure)

Замыкание (closure) в JavaScript — это мощный механизм, который позволяет функциям "запоминать" свое лексическое окружение (область видимости), даже после того, как внешняя функция завершила выполнение. Замыкания часто используются для создания приватных переменных, реализации функций высшего порядка и других паттернов программирования.

Как работает замыкание?

Когда функция создается, она запоминает ссылку на свое лексическое окружение (все переменные, которые были доступны в момент ее создания). Даже если внешняя функция завершила выполнение, внутренняя функция сохраняет доступ к переменным из этого окружения.

Пример замыкания

function outer() {
let outerVar = "Я из внешней функции";

function inner() {
console.log(outerVar); // Используем переменную из внешней функции
}

return inner;
}

const closureFunc = outer(); // outer завершила выполнение
closureFunc(); // "Я из внешней функции" — inner помнит outerVar

Здесь:

  1. Функция outer создает переменную outerVar.
  2. Функция inner использует эту переменную.
  3. Когда outer завершает выполнение, она возвращает inner.
  4. Переменная closureFunc теперь содержит функцию inner, которая сохраняет доступ к outerVar.

Почему это работает?

JavaScript использует лексическую область видимости (lexical scoping). Это означает, что область видимости функции определяется в момент ее создания, а не в момент вызова. Внутренняя функция (inner) "замыкается" на переменные из внешней функции (outer), даже если внешняя функция уже завершила выполнение.

Практическое применение замыканий

  1. Приватные переменные
    Замыкания позволяют создавать приватные переменные, которые недоступны извне.
function createCounter() {
let count = 0; // Приватная переменная

return function() {
count++;
return count;
};
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

Здесь переменная count недоступна извне, но функция-счетчик может изменять и возвращать ее значение.

  1. Функции высшего порядка
    Замыкания часто используются в функциях высшего порядка, таких как map, filter, reduce.
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}

const double = createMultiplier(2);
console.log(double(5)); // 10

Здесь createMultiplier возвращает функцию, которая "запоминает" значение multiplier.

  1. Модули и инкапсуляция
    Замыкания позволяют создавать модули с приватными методами и переменными.
const module = (function() {
let privateVar = "Я приватная";

function privateMethod() {
console.log(privateVar);
}

return {
publicMethod: function() {
privateMethod();
}
};
})();

module.publicMethod(); // "Я приватная"
console.log(module.privateVar); // undefined (недоступно)
  1. Колбэки и асинхронный код
    Замыкания часто используются в асинхронном коде, чтобы сохранить состояние. Здесь функция внутри setTimeout "запоминает" значение name.
function delayedGreeting(name) {
setTimeout(function() {
console.log(`Привет, ${name}!`);
}, 1000);
}
delayedGreeting("Алексей"); // Через 1 секунду: "Привет, Алексей!"

Здесь функция внутри setTimeout "запоминает" значение name.

Как избежать утечек памяти?

Замыкания могут приводить к утечкам памяти, если они сохраняют ссылки на большие объекты, которые больше не используются. Чтобы избежать этого:

  • Убедитесь, что замыкания не сохраняют ненужные данные.
  • Используйте null для очистки ссылок, когда они больше не нужны.

🚀 Источник: DeepSeek
🚀 Доп. источник: https://learn.javascript.ru/closure