Suggest an editImprove this articleRefine the answer for “What closures are used for”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A closure is a function that remembers the lexical environment it was created in and can reach its variables even after the outer function has finished. That gives you private data and encapsulation without classes, function factories with configuration baked in, state kept between calls (counters, event handlers), result caching (memoization), and the basic functional programming techniques: currying, partial application, compose. A closure is created automatically every time you declare a function inside another function.** ```javascript function makeCounter() { let count = 0; // private state return () => ++count; // the closure remembers it } const next = makeCounter(); next(); // 1 next(); // 2 ``` **Key point:** a closure keeps a reference to the environment, not a copy of the values, which makes it a ready-made mechanism for private state that survives between calls.Shown above the full answer for quick recall.Answer (EN)Image**A closure is a function that "remembers" its lexical (outer) scope even when it runs outside of that scope.** In other words, a function can reach the variables of the place where it was created, not of the place where it is called, and that single property is what private data, function factories, caches and most functional programming patterns are built on. ## Theory ### TL;DR - A closure is the pair "function + the lexical environment it was created in". - The inner function holds a reference to the outer environment, so those variables do not vanish when the outer call returns. - Main uses: private data, function factories, state between calls, memoization, currying. - Closures are created automatically; you do not have to do anything special. - A closure keeps a reference to the variable, not a snapshot of its value. - Unneeded captured references keep memory alive, so large objects in a captured scope are a real leak risk. ### Quick example ```javascript function outer() { let count = 0; function inner() { count++; console.log(count); } return inner; } const counter = outer(); counter(); // 1 counter(); // 2 counter(); // 3 ``` What happens here: - `outer()` returns `inner`; - `inner` remembered the `count` variable from its lexical environment; - even after `outer()` has finished, `count` does not disappear; - that is a closure, the "saved memory" of a function. ### Private data and encapsulation Variables of the outer function are unreachable from outside but available to every function created inside it. That gives private state without classes and without `#` fields: ```javascript function createUser(name) { let score = 0; return { getName() { return name; }, addScore() { score++; }, getScore() { return score; } }; } const user = createUser('Oleh'); user.addScore(); user.addScore(); console.log(user.getName(), user.getScore()); // Oleh 2 ``` Here `score` is a private variable: `user.score` does not exist, nothing outside can read or corrupt it, yet `addScore` and `getScore` have full access. The module pattern is built the same way: only the public API is returned, everything else stays in the captured scope. ### Function factories and configured handlers A closure lets you bake configuration into a function at creation time: ```javascript function makeMultiplier(factor) { return function(num) { return num * factor; }; } const double = makeMultiplier(2); const triple = makeMultiplier(3); console.log(double(5)); // 10 console.log(triple(5)); // 15 ``` Each created function has its own `factor` and remembers which multiplier it was created with. Currying, partial application and composition rest on the same mechanism: applying some arguments early is just returning a function that has closed over them. ### Keeping state: event handlers and memoization An event handler outlives the function that subscribed it and still sees that function's variables: ```javascript function setupButton(id) { let clicks = 0; document.getElementById(id).addEventListener('click', () => { clicks++; console.log(`Clicks on button ${id}: ${clicks}`); }); } setupButton('save'); setupButton('cancel'); ``` Every handler remembers its own `clicks` variable, even after `setupButton` has returned. The same trick gives a cache that survives across calls: ```javascript function memoize(fn) { const cache = {}; return function(arg) { if (cache[arg]) { console.log('From cache:', arg); return cache[arg]; } const result = fn(arg); cache[arg] = result; console.log('Computed:', arg); return result; }; } const square = memoize(x => x * x); square(4); // Computed: 4 square(4); // From cache: 4 ``` The `cache` object exists only inside the closure: it is unreachable from outside and does not pollute the global scope. ### How it works under the hood When a function is created, the engine builds a Lexical Environment for it: an internal object holding the variables declared in that scope plus a reference to the outer environment. If an inner function uses an outer variable, it keeps a reference to that environment, so the garbage collector cannot reclaim it while the function is alive. That is exactly why the outer function's variables remain reachable after it returns. You never have to opt in: a closure is formed every time you declare a function inside another one. ```javascript function outer() { const a = 42; return function() { console.log(a); // this is a closure }; } ``` ### Where closures are used in practice | Scenario | Example | | --- | --- | | Private data | Hide variables inside a function, expose only methods | | Function factories | Generators, configured handlers | | Modules and encapsulation | Splitting logic without global variables | | Caching (memoization) | Keep computed results between calls | | Counters and state | Hold state across invocations | | Callbacks and event handlers | Access outer data from inside a function | | Functional programming | Currying, partial application, compose | ### Common mistakes - **Assuming a closure copies the value.** It holds a reference to the variable: change the variable after the function was created and the function sees the new value. - **`var` inside a loop.** The classic trap: every callback closes over the same variable and sees the last value. `let` creates a fresh binding per iteration and fixes it. - **Ignoring memory.** A captured scope lives as long as the function does. A handler that closed over a big object or a DOM node keeps them alive until it is removed. - **Creating heavy closures in hot code.** Each factory call builds a new environment and a new function object; inside a million-iteration loop that shows up in profiles. - **Confusing closures with `this`.** Closures are about variables; `this` is decided by the call site and is not captured (except in arrow functions, which take it lexically).For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.