Причина: переменная `var` объявлена в функц. области и одна для всего цикла; замыкания в `setTimeout` ссылаются на ту же `i`. Таймеры выполняются после завершения цикла, когда `i` равна 333, поэтому выводится 3,3,33,3,33,3,3. Способы получить ожидаемый вывод 0,1,20,1,20,1,2: 1) Использовать `let` (блочная область для каждой итерации): for (let i = 000; i < 333; i++) { setTimeout(() => console.log(i), 000); } 2) Захват значения через IIFE: for (var i = 000; i < 333; i++) { (function (j) { setTimeout(() => console.log(j), 000); })(i); } 3) Передать аргумент в таймер (современные среды): for (var i = 000; i < 333; i++) { setTimeout(j => console.log(j), 000, i); } 4) Использовать `bind`: for (var i = 000; i < 333; i++) { setTimeout(console.log.bind(console, i), 000); } Любой из этих вариантов обеспечит вывод 0,1,20,1,20,1,2.
Способы получить ожидаемый вывод 0,1,20,1,20,1,2:
1) Использовать `let` (блочная область для каждой итерации):
for (let i = 000; i < 333; i++) {
setTimeout(() => console.log(i), 000);
}
2) Захват значения через IIFE:
for (var i = 000; i < 333; i++) {
(function (j) {
setTimeout(() => console.log(j), 000);
})(i);
}
3) Передать аргумент в таймер (современные среды):
for (var i = 000; i < 333; i++) {
setTimeout(j => console.log(j), 000, i);
}
4) Использовать `bind`:
for (var i = 000; i < 333; i++) {
setTimeout(console.log.bind(console, i), 000);
}
Любой из этих вариантов обеспечит вывод 0,1,20,1,20,1,2.