Programming Fundamentals › Functional Programming
Closure
A function that remembers variables from the place it was defined.
Also known as: closures, lexical closure
A closure is a function that keeps access to the variables from the place where it was created, even after that place has finished running.
function makeCounter() {
let count = 0;
return () => ++count; // remembers `count`
}
const next = makeCounter();
next(); // 1
next(); // 2
makeCounter has returned, yet count is still alive because the inner function holds on
to it. Each call to makeCounter() makes a separate count, so counters don’t interfere.
Where you meet them
You use closures constantly without naming them: event handlers that read variables from
the surrounding function, callbacks passed to setTimeout or fetch, React hooks, and
functions that return configured functions (makeValidator(minLength)).
function makeValidator(min) {
return (text) => text.length >= min; // `min` captured
}
const isValidName = makeValidator(3);
The classic bug: loops
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // prints 3, 3, 3
}
With var, there is one i shared by all three callbacks, and the loop has finished before
they run. With let, each iteration gets its own i and it prints 0, 1, 2. Python has the
same trap with lambdas created in a loop: they look up the variable when called.
Another trap: stale values
A closure captures the variable, but a framework may call your function again with new values. In React, an effect or callback can keep seeing an old value of state if its dependencies are wrong. When something “doesn’t update”, ask which closure is holding the old value.