Skip to main content

Closures

A closure is a function together with the lexical environment it was created in. The function keeps access to the variables of its outer scope even after the outer function has finished. Every function in JavaScript is a closure; the term matters when the function outlives its outer scope.

Details​

Where Closures Are Used​

  • Private state: variables that can be changed only through the returned functions.
  • Function factories and helpers such as once, memoize, debounce.
  • Callbacks: event handlers, timers and promise callbacks that use variables of the surrounding code.

What to Watch For​

  • The closure sees the variable, not a copy of its value. It reads the value that the variable has at the time of the call.
  • Memory. Everything the closure references stays in memory while the closure itself is reachable. A forgotten handler or timer that references a large object is a typical leak. See Garbage Collection.

Example​

function createCounter() {
let count = 0;

return {
increment: () => ++count,
reset: () => {
count = 0;
},
};
}

const counter = createCounter();

console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.count); // undefined: the variable is private

Follow-up Questions​

What does this code print and how do you fix it?

for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i));
}
// 3 3 3
  • var creates one variable for the whole loop. All three callbacks close over it and run after the loop has ended.
  • Fix: let i creates a new variable for every iteration, so the output is 0 1 2.

Other questions:

  • Why does a closure work at all? A function keeps a reference to the environment where it was defined. See Execution Context.
  • Write once(fn) or memoize(fn). Both keep their state in a closure; see Common Coding Tasks.

Common Mistakes​

  • "A closure stores a snapshot of the values." It stores a reference to the variables.
  • "A closure is a function inside a function." Nesting is not required; what matters is the access to outer variables.