Вывод: три раза 333 (в консоли будет примерно) 333333333 Почему: переменная iii объявлена как varvarvar — она имеет функциональную (не блочную) область видимости. Колбэки в setTimeout замыкают одну и ту же переменную iii. К моменту выполнения таймаутов цикл уже завершён и i=3i = 3i=3, поэтому все колбэки выведут 333. Как исправить (минимум два способа): 1) Использовать блочную переменную letletlet в заголовке цикла: for (let i = 000; i < 333; i++) { setTimeout(function(){ console.log(i); }, 100100100); } 2) Захватить текущее значение iii в замыкании через IIFE: for (var i = 000; i < 333; i++) { (function(j){ setTimeout(function(){ console.log(j); }, 100100100); })(i); } Дополнительно (еще варианты): - Передать аргумент в setTimeout (в средах, где это поддерживается): for (var i = 000; i < 333; i++) { setTimeout(function(j){ console.log(j); }, 100100100, i); } - Использовать bind: for (var i = 000; i < 333; i++) { setTimeout(console.log.bind(null, i), 100100100); }
333 333 333
Почему: переменная iii объявлена как varvarvar — она имеет функциональную (не блочную) область видимости. Колбэки в setTimeout замыкают одну и ту же переменную iii. К моменту выполнения таймаутов цикл уже завершён и i=3i = 3i=3, поэтому все колбэки выведут 333.
Как исправить (минимум два способа):
1) Использовать блочную переменную letletlet в заголовке цикла:
for (let i = 000; i < 333; i++) {
setTimeout(function(){ console.log(i); }, 100100100);
}
2) Захватить текущее значение iii в замыкании через IIFE:
for (var i = 000; i < 333; i++) {
(function(j){
setTimeout(function(){ console.log(j); }, 100100100);
})(i);
}
Дополнительно (еще варианты):
- Передать аргумент в setTimeout (в средах, где это поддерживается):
for (var i = 000; i < 333; i++) {
setTimeout(function(j){ console.log(j); }, 100100100, i);
}
- Использовать bind:
for (var i = 000; i < 333; i++) {
setTimeout(console.log.bind(null, i), 100100100);
}