What is a closure in JavaScript?

JavaScript Functions & Scope Intermediate 1–2 Yrs2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

A closure is a function bundled with references to the variables from the scope where it was defined. Even after that outer function has returned, the inner function still “closes over” and can read and update those variables. Closures power data privacy, function factories, memoisation and most callback patterns.

A closure is a function together with the variables from where it was defined. So if I return a function from inside another function, that inner function still has access to the outer function's variables even after the outer one has finished running. It's how you get private state in JavaScript — the variables aren't reachable from outside, only through the functions you return. The classic gotcha is a for loop with var and setTimeout: every callback closes over the same variable and prints the last value. Switching to let gives each iteration its own binding.

JavaScript uses lexical scoping: a function can see variables in the scope it was written in. A closure is what keeps those variables alive because a nested function still refers to them.

  • Private state — variables in the outer function aren't accessible from outside, only through the returned functions.
  • Factories — makeAdder(5) returns a function that remembers 5.
  • The classic loop bug — with var, all callbacks in a for loop share one binding and see the final value; let creates a fresh binding per iteration and fixes it.

JavaScript — closure for private state
function createCounter() {
  let count = 0;                 // private
  return {
    increment: () => ++count,
    value: () => count,
  };
}

const c = createCounter();
c.increment();
c.increment();
console.log(c.value()); // 2  — 'count' is not accessible any other way

// loop bug
for (var i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 3 3 3
for (let j = 0; j < 3; j++) setTimeout(() => console.log(j)); // 0 1 2