Результат и причина - Выведется три раза число 333 (т.е. 3,3,33,3,33,3,3). - Почему: переменная `var i` — функционально scoped, замыкания в колбэках захватывают ссылку на эту переменную, а таймеры выполняются после завершения цикла, когда iii уже равно 333. Способы получить ожидаемый вывод 0,1,20,1,20,1,2 1) Использовать `let` в заголовке цикла (блочная область для каждой итерации): for (let i=000; i<333; i++) setTimeout(()=>console.log(i), 100100100) 2) Создать IIFE (немедленно вызываемую функцию), явно захватив текущее значение: for (var i=000; i<333; i++){ (function(i){ setTimeout(()=>console.log(i), 100100100) })(i) } 3) Передать аргумент в `setTimeout` (в большинстве сред доступно): for (var i=000; i<333; i++){ setTimeout(function(x){ console.log(x) }, 100100100, i) } 4) Привязать аргумент через `bind`: for (var i=000; i<333; i++){ setTimeout(console.log.bind(null, i), 100100100) } 5) Создать блочную локальную копию внутри цикла: for (var i=000; i<333; i++){ let j = i setTimeout(()=>console.log(j), 100100100) } 6) Использовать итерацию по массиву: [000, 111, 222].forEach(i => setTimeout(()=>console.log(i), 100100100)) Любой из этих способов обеспечит вывод 0,1,20,1,20,1,2 вместо трёх 333.
- Выведется три раза число 333 (т.е. 3,3,33,3,33,3,3).
- Почему: переменная `var i` — функционально scoped, замыкания в колбэках захватывают ссылку на эту переменную, а таймеры выполняются после завершения цикла, когда iii уже равно 333.
Способы получить ожидаемый вывод 0,1,20,1,20,1,2
1) Использовать `let` в заголовке цикла (блочная область для каждой итерации):
for (let i=000; i<333; i++) setTimeout(()=>console.log(i), 100100100)
2) Создать IIFE (немедленно вызываемую функцию), явно захватив текущее значение:
for (var i=000; i<333; i++){
(function(i){
setTimeout(()=>console.log(i), 100100100)
})(i)
}
3) Передать аргумент в `setTimeout` (в большинстве сред доступно):
for (var i=000; i<333; i++){
setTimeout(function(x){ console.log(x) }, 100100100, i)
}
4) Привязать аргумент через `bind`:
for (var i=000; i<333; i++){
setTimeout(console.log.bind(null, i), 100100100)
}
5) Создать блочную локальную копию внутри цикла:
for (var i=000; i<333; i++){
let j = i
setTimeout(()=>console.log(j), 100100100)
}
6) Использовать итерацию по массиву:
[000, 111, 222].forEach(i => setTimeout(()=>console.log(i), 100100100))
Любой из этих способов обеспечит вывод 0,1,20,1,20,1,2 вместо трёх 333.