+ 7

Помогите понять код

for(var i=0; i<10; i++) { setTimeout(function () { alert(i); }, 100); } Почему этот код выведет 10 раз число 10

10th Nov 2019, 8:32 AM
Kate Marina
Kate Marina - avatar
11 odpowiedzi
+ 7
Замечание на ответ от id001x: ... Если изменить на вот так for(var i=0; i<10; i++) { setTimeout(alert(i),100); } То все работает как предполагается. Но, безусловно я могу и ошибаться и есть ещё какой то нюанс. ... тут происходит другой процесс, а именно в цикле хоть и вызывается функция вызова по таймеру setTimeout, но в качестве параметра со ссылкой на обьект функции ей передали по сути результат вызова функции alert(i) , что конечно некорректно, но и не является ошибкой, с точки зрения функции setTimeout, она просто делать ничего не будет... а вот функция alert конечно отработает столько раз сколько ее пнут и с текущим для итерации цикла значением переменной i.
11th Nov 2019, 11:16 PM
Michail Getmanskiy
Michail Getmanskiy - avatar
+ 4
Так как для выполнения цикла for в данном случае надо явно меньше 100мс то в функцию передается значение которое находится в "i" на момент окончания выполнения кода, т.е. 10 . В итоге получили функцию которая выводит 10 раз по 10
10th Nov 2019, 8:39 PM
id001x
id001x - avatar
11th Nov 2019, 6:33 PM
Mahfuj Hasan
Mahfuj Hasan - avatar
+ 3
в параметре функции setTimeout указано - обьявить анонимную функцию с телом, в котором применяется переменная i, с этого момента функция эта ссылается на переменную i, хоть и обьявленную в цикле, но видимую и вне него. Такая анонимная функция обьявляется при каждой итерации цикла, но эти функцию не выполняются а ждут, момента когда логика таймера функции setTimeout их вызовет, что и произойдет через указанное время, которое, да больше времени цикла явно. К этому времени переменная i циклом будет приведена к значению 10, и именно это значение будет использовано в них при выполнении. Такое поведение связи с переменной вне функции называется замыканием, если я ничего не путаю
11th Nov 2019, 11:02 PM
Michail Getmanskiy
Michail Getmanskiy - avatar
+ 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); } То все работает как предполагается. Но, безусловно я могу и ошибаться и есть ещё какой то нюанс.
10th Nov 2019, 10:56 AM
id001x
id001x - avatar
+ 2
В цикле for мы назначаем счётчик i от 0 до меньше 10, с приращением i на единицу мы выводим встроенную функцию setTimeout, внутри которой вызываем собственную функцию "function", в теле которой вызываем всплывающее модальное окно alert с параметром i https://learn.javascript.ru/settimeout-setinterval
10th Nov 2019, 4:04 PM
Yaroslav Vernigora
Yaroslav Vernigora - avatar
+ 2
Ярослав Вернигора (Yaroslav Vernigora) таки да... В конце даже пример очень похожий есть. В функцию передается только последнее значение , в нашем случае - 10.
10th Nov 2019, 6:53 PM
id001x
id001x - avatar
+ 2
Michail Getmanskiy Понятно, спасибо 🙃
12th Nov 2019, 6:40 AM
id001x
id001x - avatar
0
Только я не могу понять, почему выводится только значение 10
10th Nov 2019, 8:36 PM
Yaroslav Vernigora
Yaroslav Vernigora - avatar
0
Запускается цикл for, который выполняет код x раз, в данном случае от 0 !!!ВКЛЮЧИТЕЛЬНО!!! и до меньше 10 (10-1=9). В функцию setTimeout мы передаём callback функцию, в которой функция alert ссылается на переменную I i и выводит спустя 100ms (что мы и указали во втором параметре setTimeout). Для полного выполнения цикла потребуется менее 100ms, что и является проблемой. После окончания цикла - у нас будет конечная переменная i, равная 10, её функция таймера и будет выводить.
11th Nov 2020, 7:08 AM
x2PI Dev
x2PI Dev - avatar