devnotes.

Closures Explained

A closure is a function that "remembers" the variables from its enclosing scope even after that outer function has already finished running.

function makeCounter() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();
counter(); // 1
counter(); // 2

Here, count survives between calls to counter() because the returned inner function keeps a live reference to the variables in makeCounter's scope — that reference is the closure. Each call to makeCounter() creates a brand-new, independent count, so a second counter wouldn't share state with the first.

Closures are the standard pattern for private state without classes, and they underpin many everyday patterns: memoization (caching a function's results), event handler factories, and the module pattern used before ES modules existed.