Closures
Functions remember the variables they were created with — the idea behind much of JS.
- Explain what a closure is
- Use a closure to keep private state
- Recognise closures in everyday callbacks
A closure is a function bundled together with the variables that were in scope where it was defined. In plain terms: an inner function remembers the variables of the outer function that created it, even after that outer function has finished. Closures are everywhere in JavaScript, and understanding them demystifies a lot of code.
A function that remembers
function makeCounter() {
let count = 0; // local to makeCounter
return function () {
count = count + 1; // ...but the inner function still sees it
return count;
};
}
const next = makeCounter();
next(); // 1
next(); // 2makeCounter has returned, yet the function it produced still has access to
count. That captured variable lives on as long as the inner function does —
that's the closure.
Private state
Because count isn't reachable from outside, closures give you encapsulation
— the information-hiding idea from the abstraction lesson, with no class needed.
The only way to touch count is through the returned function.
Notice a and b each close over their own count — separate calls to
makeCounter create separate environments.
You're already using them
Every callback that uses a variable from its surroundings is a closure:
const factor = 3;
[1, 2, 3].map((n) => n * factor); // the arrow closes over `factor`This is why callbacks "just work" with the variables around them — and, later, why event handlers and async callbacks can see the state from where they were defined.
Where to go next
Next: promises in depth — composing and handling asynchronous results (building on the event-loop lesson).