Explain closures. Then explain the classic var-in-a-loop bug and how to fix it.
Whether you understand that functions capture their lexical environment, not a snapshot of values.
A closure is a function bundled with references to its surrounding lexical scope — it keeps those variables alive after the outer function returns. The loop bug: with var, all three callbacks close over the SAME single i, which is 3 by the time they run. Fix with let (block-scoped — a fresh binding per iteration) or an IIFE that captures the current value as an argument. The mental model that unlocks every closure question: a closure captures the variable, not its value at capture time — so a later mutation is visible to the closure. That's why `var` (one function-scoped binding shared by all iterations) misbehaves while `let` (a new binding created per loop iteration) works. Closures are also how JavaScript gets private state without a `private` keyword: variables in the outer scope are reachable only through the returned function.
Closures power data privacy (module pattern), function factories, memoization, and every React hook's captured state.