Question 14 / 14

Can an IIFE fix the setTimeout loop without using let?

Topic: Closures

Calling an immediately invoked function with i as its argument gives each iteration its own parameter binding.

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

Predict the output

Predict the output. The loop still uses var — does wrapping the callback in an IIFE change what each timer logs?

for (var i = 0; i < 3; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i);
    }, 100);
  })(i);
}
Reveal the answer and explanation

Expected output

0
1
2

Why this happens

On every iteration, (function(i) {...})(i) is called immediately with the current value of the shared loop variable, copying that value into a brand-new parameter binding named i.

The setTimeout callback closes over the IIFE’s parameter i, not the outer loop’s i, so each of the three callbacks captures a different, private binding.

When the timers fire after the loop finishes, each callback reads its own parameter binding and logs the value it was called with: 0, then 1, then 2.

What this question tests

  • an IIFE argument creates a fresh binding per call
  • the inner callback closes over the parameter, shadowing the outer var
  • a classic pre-ES6 substitute for let’s per-iteration scoping

Runtime assumptions

The visualizer treats each IIFE invocation as its own function call with its own Activation Object, so the three parameter bindings for i never collide, in any standard JavaScript runtime.

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