+ 7
Помогите понять код
for(var i=0; i<10; i++) { setTimeout(function () { alert(i); }, 100); } Почему этот код выведет 10 раз число 10
11 ответов
+ 7
Замечание на ответ от id001x:
...
Если изменить на вот так
for(var i=0; i<10; i++) {
setTimeout(alert(i),100);
}
То все работает как предполагается. Но, безусловно я могу и ошибаться и есть ещё какой то нюанс.
...
тут происходит другой процесс, а именно в цикле хоть и вызывается функция вызова по таймеру setTimeout, но в качестве параметра со ссылкой на обьект функции ей передали по сути результат вызова функции alert(i) , что конечно некорректно, но и не является ошибкой, с точки зрения функции setTimeout, она просто делать ничего не будет... а вот функция alert конечно отработает столько раз сколько ее пнут и с текущим для итерации цикла значением переменной i.
+ 4
Так как для выполнения цикла for в данном случае надо явно меньше 100мс то в функцию передается значение которое находится в "i" на момент окончания выполнения кода, т.е. 10 . В итоге получили функцию которая выводит 10 раз по 10
+ 3
в параметре функции setTimeout указано - обьявить анонимную функцию с телом, в котором применяется переменная i, с этого момента функция эта ссылается на переменную i, хоть и обьявленную в цикле, но видимую и вне него.
Такая анонимная функция обьявляется при каждой итерации цикла, но эти функцию не выполняются а ждут, момента когда логика таймера функции setTimeout их вызовет, что и произойдет через указанное время, которое, да больше времени цикла явно. К этому времени переменная i циклом будет приведена к значению 10, и именно это значение будет использовано в них при выполнении.
Такое поведение связи с переменной вне функции называется замыканием, если я ничего не путаю
+ 2
Прикольный пример. В js я не силен, но если пример переписать в вот такой вот вид
for(var i=0; i<10; i++) {
setTimeout(function(){alert(i);},100);
alert(i);
}
То мысль только одна. Значение в alert(i) которое находится внутри функции передается таким, которым является на момент вызова функции после таймаута, т.е.10
И функция вызывается 10 раз.
Если изменить на вот так
for(var i=0; i<10; i++) {
setTimeout(alert(i),100);
}
То все работает как предполагается. Но, безусловно я могу и ошибаться и есть ещё какой то нюанс.
+ 2
В цикле for мы назначаем счётчик i от 0 до меньше 10, с приращением i на единицу мы выводим встроенную функцию setTimeout, внутри которой вызываем собственную функцию "function", в теле которой вызываем всплывающее модальное окно alert с параметром i
https://learn.javascript.ru/settimeout-setinterval
+ 2
Ярослав Вернигора (Yaroslav Vernigora) таки да... В конце даже пример очень похожий есть. В функцию передается только последнее значение , в нашем случае - 10.
+ 2
Michail Getmanskiy Понятно, спасибо 🙃
0
Только я не могу понять, почему выводится только значение 10
0
Запускается цикл for, который выполняет код x раз, в данном случае от 0 !!!ВКЛЮЧИТЕЛЬНО!!! и до меньше 10 (10-1=9).
В функцию setTimeout мы передаём callback функцию, в которой функция alert ссылается на переменную I
i и выводит спустя 100ms (что мы и указали во втором параметре setTimeout).
Для полного выполнения цикла потребуется менее 100ms, что и является проблемой. После окончания цикла - у нас будет конечная переменная i, равная 10, её функция таймера и будет выводить.