Suggest an editImprove this articleRefine the answer for “Loop with var and setTimeout”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Because of two things at once: `var` has function scope, so the loop creates only one `i` variable for the whole function instead of a new one per iteration, and `setTimeout` runs later, after the loop has already finished. **Key point:** every `setTimeout` callback closes over the same final value of `i`, so you need to use `let` or isolate the value through a closure or an argument.Shown above the full answer for quick recall.Answer (EN)ImageBecause of two things at once: 1. `var` **has function scope.** In the loop `for (var i = 0; i < 3; i++) { ... }`, only **one** `i` variable is created for the whole function, not a new one per iteration. Every `setTimeout` callback closes over **the same** value of `i`. 2. `setTimeout` **runs later.** Callbacks land in the macrotask queue and run **after the current JS stack empties out**. By the time the first timer fires, the loop has already finished, and `i` holds its **final value** (for example, 3). ### The symptom ```javascript for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // 3 // 3 // 3 ``` ### How to fix it **Option 1 -** `let` **(block scope):** ```javascript for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); // 0, 1, 2 } ``` **Option 2 - an IIFE/closure that passes the current** `i`**:** ```javascript for (var i = 0; i < 3; i++) { (function (j) { setTimeout(() => console.log(j), 0); // 0, 1, 2 })(i); } ``` **Option 3 - pass it as an argument to** `setTimeout`**:** ```javascript for (var i = 0; i < 3; i++) { setTimeout(j => console.log(j), 0, i); // 0, 1, 2 } ``` **Option 4 -** `bind`**:** ```javascript for (var i = 0; i < 3; i++) { setTimeout(console.log.bind(null, i), 0); // 0, 1, 2 } ``` > In short: `var` gives you one "shared" variable for the whole loop, and `setTimeout` runs after the loop has already finished. Use `let`, or isolate the value through a closure or an argument.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.