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
2Why 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.