Skip to content
Astera Technology

Keep independent state in separate closures

Interleave two counters and identify which stored value each call advances.

Download complete case notes and answer keys ↓

Trace the fixed program

Create a and b from the same counter factory. Follow the supplied call order without adding a global counter.

Complete original program
function counter(){let value=0;return ()=>++value;}
const a=counter(),b=counter();
console.log(JSON.stringify([a(),a(),b(),a(),b()]));
Exact console output
[1,2,1,3,2]
Values and execution
Call sequenceResultStored state afterward
a(), a()1, 2a=2; b=0
b(), a(), b()1, 3, 2a=3; b=2

Explain the result

Each counter() call creates a new value binding. The returned function retains that environment after the factory returns. The state lasts while the function remains reachable; this is neither persistent storage nor an authorization boundary.

Test the alternative

Moving value outside the factory couples the instances. This fresh alternative produces one shared sequence.

Separate finite alternative
let value=0;function counter(){return ()=>++value;}
const a=counter(),b=counter();
console.log(JSON.stringify([a(),a(),b(),a(),b()]));
Alternative output
[1,2,3,4,5]

Work the boundary case

After the original five calls, what do a(), b(), and a new counter()() return?

Show the worked answer

4, 3, and 1. The new factory call starts another environment at zero.

Fresh boundary program
function counter(){let value=0;return ()=>++value;}
const a=counter(),b=counter();[a(),a(),b(),a(),b()];
console.log(JSON.stringify([a(),b(),counter()()]));
Boundary output
[4,3,1]

Original example files