当我在for循环中调用setTimeout时发生了什么?

当我在for循环中调用setTimeout时发生了什么?

问题描述:

请运行该代码片段,就像你看到的,控制台输出如下:当我在for循环中调用setTimeout时发生了什么?

1 
... 
5 
6 (5 times) 

所以,据我所知,setTimeout创建一个新的函数栈,但i<=5应时i == 5停下来,这样我就可以”不明白为什么6

This is MDN about explain setTimeout.

从1到5我是很容易理解,但是发生了什么事时,电话setTimeout,以及如何解释6控制台存在吗?

for(var i = 1; i <= 5; i++) { 
 
    console.log(i) 
 
    setTimeout(function() { 
 
     console.log(i) 
 
    }, 0) 
 
}

+0

循环首先被执行,然后是延迟函数,那时'i'的值是6.另外,'timer'和'clearInterval'对于代码中的'setTimeout' – Teemu

+0

@Teemu我删除了我的另一个演示版本留下的一些无意义的代码。 –

第一console.log呼叫被连续运行五次的setTimeout的那些曾经在开始之前。然后,i是6,并且console.log(i)被称为那些全部排队的五次。

当您运行setTimeout时,它会返回定时器的句柄。你实际上没有对返回值做任何事情,但它仍然在队列中。

另外,超时值0在技术上并不意味着“立即运行”,它只是意味着“添加到队列的顶部”。

for(let i = 1; i <= 5; i++) { 
 
    setTimeout(function() { 
 
     console.log(i) 
 
    }, 0) 
 
}

变种创建未作用域for循环的块(它不是块作用域),而让这是否一个变量。因此,使用setTimeout调用创建的函数将全部查看相同的var,因此可以打印6(它的值在他们有机会运行的时间,而let,它们在这个块范围变量上有一个闭包,因此所有正确地打印它们的预期值,1..5。