JavaScript

Небольшой вопрос по JS

"for(var i=0 ; i<5; ++i){
setTimeout(function(){
console.log(i)
},i*1000)
}"
Почему этот код печатает 5 раз цифру 5,а не по очереди от 1 до 5?просьба объяснить.
Потому что за один цикл запускаешь пять таймеров

setTimeout(function(){
console.log(i)
},i*1000)

Когда они сработают цикл уже закончится и (i) будет содержать цифру 5

Но если эта сделать так то тогда будет создана каждая индивидуальная функция которая запустит таймер со своим значением i Это выглядит так на стрелочной функции

for(var i=0 ; i<6; ++i){

(i=>setTimeout(()=>console.warn(i),i*1000))(i);

}

АЛ
Алексей Латух
72 170
Лучший ответ
Вместо var используй let, тогда область видимости i будет ограничена циклом и JS ничего не останется, как запоминать её. Ну или создавай замыкание, в котором сохраняй i и отдавай его в свою асинхронную функцию.
Коля Суров
Коля Суров
63 056
Потому что анонимная функция в первом аргументе setTimeout() выполнится асинхронно - ПОСЛЕ цикла for, и после вообще всего синхронного кода.
На момент ее выполнения, i будет содержать "последнее значение + 1", так как сначала выполняется инкремент ++,и только затем проверка условия <5.
́
setTimeout(func, delay) возвращает управление синхронному коду СРАЗУ, а не блокирует его выполнение на время delay.
И, если синхронный код будет выполняться N миллисекунд, то func будет вызвана спустя delay+N миллисекунд.
́
Создание функций в цикле - хоть и широко применяется, но является плохим стилем написания кода. Старайтесь этого избегать, объявляя функции вне циклов, и используя массивы (это сделает код оптимальнее, гибче, и повысит удобство его отладки).
потому что i за областью видимости цикла

for( var i = 0; i < 5; ++i )
( function( i ) {
setTimeout( function() {
console.log( i );
}, i * 1000 );
})( i );
Сергей Полубояров Можно было просто заменять var на let
Неизвестно Неизвестно Неверно. Если бы переменная была за областью видимости, то выводилось бы undefined вместо значения.