setTimeout在JavaScript中使用Loop
我有一个非常微不足道的问题。 对于setTimeout的简单循环,如下所示:
for (var count = 0; count < 3; count++) {
setTimeout(function() {
alert("Count = " + count);
}, 1000 * count);
}
控制台提供如下输出:
Count = 3
Count = 3
Count = 3
不知道为什么这样的输出。 任何人都可以解释,请吗?
这与JavaScript中如何处理范围和提升有关。
代码中会发生什么,JS引擎会将您的代码修改为:
var count;
for (count = 0; count < 3; count++) {
setTimeout(function() {
alert("Count = " + count);
}, 1000 * count);
}
当setTimeout()
正在运行它首先会在以后它自己的范围看起来count
,但它不会觉得这样的话,它会启动(这就是所谓的闭包)看向关闭功能在setTimeout
功能,直到它找到var count
语句,它将具有值3,因为循环将在第一个超时函数执行之前完成。
更多的代码解释你的代码实际上看起来像这样:
//first iteration
var count = 0; //this is 1 because of count++ in your for loop.
for (count = 0; count < 3; count++) {
setTimeout(function() {
alert("Count = " + 1);
}, 1000 * 1);
}
count = count + 1; //count = 1
//second iteration
var count = 1;
for (count = 0; count < 3; count++) {
setTimeout(function() {
alert("Count = " + 2);
}, 1000 * 2);
}
count = count + 1; //count = 2
//third iteration
var count = 2;
for (count = 0; count < 3; count++) {
setTimeout(function() {
alert("Count = " + 3);
}, 1000 * 3);
}
count = count + 1; //count = 3
//after 1000 ms
window.setTimeout(alert(count));
//after 2000 ms
window.setTimeout(alert(count));
//after 3000 ms
window.setTimeout(alert(count));
想想那样:
在1000 * n毫秒结束之后,count的值是多少?
当然它会是3,因为foor循环的结束时间早于1000 * n ms的超时。
为了打印1,2,3您需要以下内容:
for (var count = 0; count < 3; count++) {
do_alert(num);
}
function do_alert(num) {
setTimeout(function() {
alert("Count = " + num);
}, 1000 * num);
}
一种不同的方法是使它成为一个closure function
(在JavaScript闭包与匿名函数中很好地解释)
for (var count = 0; count < 3; count++) {
(function(num){setTimeout(function() {
alert("Count = " + num);
}, 1000 * num)})(count);
}
这两个代码示例实际上的工作方式相似。
第一个示例在每次迭代中调用一个命名函数(do_alert)。
第二个示例在每次迭代中调用CLOSURE匿名函数(就像do_alert
一样)。
这都是SCOPE的问题。
希望有所帮助。
想想看:
count
的价值是什么? 循环完成了很久以前...