There is only one i, because var is function-scoped. All three arrow functions capture that same variable, not its value. They run after the loop has finished, when i is 3.
There are three ways to fix it:
1. Use let (the modern fix). A for loop with let creates a new binding of i for each iteration. A binding is the link between a name and its value. So each callback captures its own i.
2. Create a new function scope per iteration (the pre-ES6 fix). An IIFE (a function that runs immediately) does this: (function (j) { setTimeout(() => console.log(j)); })(i). The parameter j is a new copy for each call.
3. Pass the value as an argument. Use setTimeout(console.log, 0, i) or setTimeout(fn.bind(null, i)). These capture the current value of i, not the variable.
vargives one sharedi. Closures capture variables, not values.- The callbacks run only after the loop has finished.
letcreates a new binding ofifor each iteration.- Older fixes use an IIFE or
bindto save the current value.
- Closures (MDN) (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)developer.mozilla.org