Ответ
Замыкание (Closure) — это функция, которая «запоминает» лексическое окружение (переменные, параметры, другие функции), в котором она была создана, даже после того, как это внешнее окружение завершило выполнение. Это фундаментальная концепция JavaScript, активно используемая в Node.js.
Простой пример:
function createCounter() {
let count = 0; // `count` — переменная в лексическом окружении createCounter
// Функция increment является замыканием
return function increment() {
count += 1; // Она имеет доступ к `count` даже после завершения createCounter
return count;
};
}
const myCounter = createCounter(); // createCounter завершилась, но её окружение «живёт» в замыкании
console.log(myCounter()); // 1
console.log(myCounter()); // 2
console.log(myCounter()); // 3
// У каждого вызова createCounter() — своё независимое замыкание с отдельной `count`.
Практическое применение в Node.js:
-
Создание приватных переменных и инкапсуляция:
function createDatabaseConnection(config) { const connectionString = config.url; // «Приватная» переменная return { connect() { console.log(`Connecting to ${connectionString}`); }, query(sql) { /* использует connectionString */ } }; } const db = createDatabaseConnection({ url: 'localhost:5432' }); // Нет прямого доступа к `connectionString` извне, только через методы. -
Фабрики и middleware: Многие библиотеки Express используют замыкания для создания конфигурируемых middleware.
function logger(format) { return function(req, res, next) { // Middleware — замыкание, помнящее `format` console.log(format, req.method, req.url); next(); }; } app.use(logger(':method :url'));
Важный нюанс: Замыкание хранит ссылку на переменную, а не её значение на момент создания. Это может приводить к классической ошибке в циклах с асинхронными операциями, которую решают с помощью let (блочная область видимости) или дополнительного замыкания.