Question 11 / 14

How does a closure preserve changing state?

Topic: Closures

The returned function keeps access to fn’s n binding after fn has returned.

Solve it with the execution visualizerStep through every binding, function call, and console output below.

Predict the output

Why do repeated x() calls continue from 21 instead of restarting at 20?

var n = 10
function fn() {
  var n = 20
  function f() {
    n++
    console.log(n)
  }
  f()
  return f
}

var x = fn()
x()
x()
console.log(n)
Reveal the answer and explanation

Expected output

21
22
23
10

Why this happens

Calling fn creates a local n binding with value 20. The first call to f increments it to 21.

fn returns the function f. Because f still references the surrounding n binding, that environment remains reachable after fn returns.

The next two x() calls update the same preserved binding to 22 and 23. The separate global n remains 10.

What this question tests

  • closure capture
  • preserved lexical environment
  • independent global binding

Runtime assumptions

The visualizer models the retained environment as specification machinery, distinct from ordinary JavaScript objects.

Specification references

JavaScript Code EditorDirectly edit or paste custom code
Step 0 of 0
StepSpaceRun
Press → (Step) or Space (Run)
Phase 1: Compilation(Hoisting & Memory Setup)
Phase 2: Execution(Line-by-line Evaluation)
Execution Step Breakdown

Press "→" / click "▶" to step line-by-line, or press "Space" / click "▶ Run" for auto-play.

Scope Chain
Lexical Environment Chain: Inner Scope → Outer [[Scope]] → Global (GO)
No active scope chain
CALL STACKStack of Execution Contexts (LIFO)
LIFO Stack Frames
Global Execution Context (GEC)
▶ Active Frame
HEAP & MEMORY SPACEAllocated Objects (GO, AO, FunctionObjects, ER)
ECMAScript Heap Area
No objects in memory
Console Output
console.log(...) Stream
No output generated yet