Files
frontend-docs/docs/javascript/04-functions/06-closure.md
2025-03-28 14:10:12 +03:00

109 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
sidebar_position: 6
---
# Замыкание (closure)
**Замыкание (closure)** в JavaScript — это мощный механизм, который позволяет функциям "запоминать" свое лексическое окружение (область видимости), даже после того, как внешняя функция завершила выполнение. Замыкания часто используются для создания приватных переменных, реализации функций высшего порядка и других паттернов программирования.
## Как работает замыкание?
Когда функция создается, она запоминает ссылку на свое лексическое окружение (все переменные, которые были доступны в момент ее создания). Даже если внешняя функция завершила выполнение, внутренняя функция сохраняет доступ к переменным из этого окружения.
## Пример замыкания
```js
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. **Приватные переменные** \
Замыкания позволяют создавать приватные переменные, которые недоступны извне.
```js
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` недоступна извне, но функция-счетчик может изменять и возвращать ее значение.
2. **Функции высшего порядка** \
Замыкания часто используются в функциях высшего порядка, таких как `map`, `filter`, `reduce`.
```js
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}
const double = createMultiplier(2);
console.log(double(5)); // 10
```
Здесь `createMultiplier` возвращает функцию, которая "запоминает" значение `multiplier`.
3. **Модули и инкапсуляция** \
Замыкания позволяют создавать модули с приватными методами и переменными.
```js
const module = (function() {
let privateVar = "Я приватная";
function privateMethod() {
console.log(privateVar);
}
return {
publicMethod: function() {
privateMethod();
}
};
})();
module.publicMethod(); // "Я приватная"
console.log(module.privateVar); // undefined (недоступно)
```
4. **Колбэки и асинхронный код** \
Замыкания часто используются в асинхронном коде, чтобы сохранить состояние.
Здесь функция внутри setTimeout "запоминает" значение name.
```js
function delayedGreeting(name) {
setTimeout(function() {
console.log(`Привет, ${name}!`);
}, 1000);
}
delayedGreeting("Алексей"); // Через 1 секунду: "Привет, Алексей!"
```
Здесь функция внутри setTimeout "запоминает" значение name.
## Как избежать утечек памяти?
Замыкания могут приводить к утечкам памяти, если они сохраняют ссылки на большие объекты, которые больше не используются. Чтобы избежать этого:
- Убедитесь, что замыкания не сохраняют ненужные данные.
- Используйте null для очистки ссылок, когда они больше не нужны.
🚀 Источник: DeepSeek \
🚀 Доп. источник: [https://learn.javascript.ru/closure](https://learn.javascript.ru/closure)