Javascript 奇怪的行为

Javascript 奇怪的行为,javascript,Javascript,如何解释这种行为 for(var i = 0; i < 4; i++) { setTimeout(function() { alert("i is: " + i); }, i * 200); } for(变量i=0;i

如何解释这种行为

for(var i = 0; i < 4; i++) {
    setTimeout(function() {
        alert("i is: " + i);
    }, i * 200);
}
for(变量i=0;i<4;i++){
setTimeout(函数(){
警惕(“我是:+i”);
},i*200);
}
这个的输出是4,4,4,4


这在文献中经常被用作危险的起吊示例。后面的输出可能是4,这是有意义的,因为i变量绑定到函数范围,因此在所有调用之间共享,到它们执行时,i将是4,完成for循环。但是,初始调用指定了一个0*200或0的超时,因此我觉得当我仍然小于4时,应该立即执行。是什么导致此函数的所有输出为4?

不是,因为它与提升无关

即使将
0
作为延迟传递,浏览器中的最小延迟大约为10ms。无论经过什么延迟,函数都不会立即执行

从:

需要注意的是,如果函数或代码段在调用
setTimeout()
的线程终止之前无法执行,则需要注意

因此,在调用任何回调之前,for的
循环已经终止

相关问题:

“但是,初始调用指定的超时为0*200或0,因此我觉得应该立即执行…”

这种情况可能发生在可以利用多线程的环境中,但在单线程环境中,当前的同步执行流将不受限制地继续,直到完成

这意味着循环将在第一次
setTimeout
回调发生之前继续并完成

即使循环需要10000毫秒才能完成,也会允许循环在第一次回调触发之前继续


尝试此演示:

var start = Date.now();

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

     // set up the first timeout
    setTimeout(function() {
        alert("i is: " + i);
    }, i * 200);

    while (Date.now() - start < 1000) ; // block for 1000 ms
}
var start=Date.now();
对于(变量i=0;i<4;i++){
//设置第一个超时
setTimeout(函数(){
警惕(“我是:+i”);
},i*200);
while(Date.now()-start<1000);//阻塞1000毫秒
}

设置第一个
setTimeout
后,我们将阻塞1000ms。
alert()
调用的结果仍然相同。这是因为同步流将继续,而与计划运行的任何异步代码无关。

在第一个计时器过期之前,对setTimeout的四个调用将在循环中触发(并且会触发匿名方法调用)。因此,当它着火时,结果总是4。setTimeout定时器延迟永远不能保证。

因为它与提升无关,所以不能保证。即使你将
0
作为延迟传递,浏览器中的最小延迟大约为10毫秒。我也认为,我在网上阅读的示例是误导性的。即。