CodeZettaInterview Hub

JavaScript · Closures · Junior · Debugging

Why does this print `3 3 3` instead of `0 1 2`, and how do you fix it? ```js for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } ```

Short Interview Answer

All callbacks close over the same function-scoped `var i`, which is `3` when they run. Use `let`, a factory, or `bind` to capture per-iteration values.

Detailed Explanation

`var i` is one binding for the loop. Each arrow closes over that binding. After the loop, `i === 3`, and the timers fire later, so all log `3`. With `let i`, each iteration gets a new binding (per ES2015 per-iteration semantics), so callbacks see 0, 1, 2. Alternatives: IIFE/`function(i){...}(i)` to copy the value, or `setTimeout(console.log, 0, i)`. This is one of the most common closure interview traps.

Example

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// 0 1 2

Interview Tip

Explain *when* the callbacks run relative to the loop — timing is the key insight.

Common Mistake

Blaming `setTimeout` itself instead of shared mutable binding.

Did you know this answer?