Javascript 在IIFE中根据循环中的标准调用setTimeout()
IIFE函数背后的逻辑和循环中Javascript 在IIFE中根据循环中的标准调用setTimeout(),javascript,loops,closures,iife,Javascript,Loops,Closures,Iife,IIFE函数背后的逻辑和循环中setTimeout()背后的逻辑是什么。 对于,有两个: for (var i = 0; i < 10; i++) { // Standard setTimeout(function() { console.log("Standard" + i); }, 1000 * i); } for (var j = 0; j < 10; j++) { // IIFE (function(j) { setTimeout(fun
setTimeout()
背后的逻辑是什么。
对于,有两个:
for (var i = 0; i < 10; i++) {
// Standard
setTimeout(function() {
console.log("Standard" + i);
}, 1000 * i);
}
for (var j = 0; j < 10; j++) {
// IIFE
(function(j) {
setTimeout(function() {
console.log("IIFE " + j);
}, 1000 * j);
})(j);
}
for(变量i=0;i<10;i++){
//标准
setTimeout(函数(){
控制台日志(“标准”+i);
},1000*i);
}
对于(var j=0;j<10;j++){
//生活
(职能(j){
setTimeout(函数(){
控制台日志(“IIFE”+j);
},1000*j);
})(j) );
}
现在,当我使用node.js运行时,10秒后会得到这个结果(每秒执行一次console.log()
):
有人能给我解释一下第一个函数调用和第二个函数调用之间的运行时逻辑差异吗?
特别是如果你能回答以下问题:
- 为什么在
的中每秒都执行日志?(忽略1000*i | j)
为什么i
的值总是10
先谢谢你
[编辑]
我不明白为什么在这两个for
中,控制台.log()
每秒都会启动一次,但超时秒数1000*I | j
可能是一个可见的超时。在第一个版本中setTimeout
在启动时引用父作用域中的变量I
,但到那时它已经改变了
在第二个示例中,您创建了一个新范围,其中包含一个
j
参数,该参数不是对父范围j
变量的引用。因此,当启动setTimeout
时,它将保持不变。为什么在这两种情况下每秒都执行日志?(忽略1000*i|j)
这是因为setTimeout()
是一个异步函数。因此,在这一步执行不会被阻止,而是使用给定的持续时间参数启动时钟并继续执行。一旦超过持续时间,就会触发事件,并将回调添加到事件循环队列中,以便逐个执行
为什么i的值总是10?
这是因为概念的不同。当第一次“标准”超时时,此时的
i
值已经是10(此时所有setTimeout
s都已注册)。而在IIFE的情况下,j
是函数中的一个形式参数,它在每次迭代后接收循环计数器变量值。此函数中包含的setTimeout
s使用此j
可能的重复项。当setTimeout执行i
的时间等于10时,您已经运行了10次循环,第二个循环中的闭包将值传递给函数,因此另一个setTimeout会记住正确的数字。除非您这样做是出于教育/实验目的,当初始化for循环中的变量时,您实际上应该只使用let
。没有iLife,变量就是一个引用,因为您使用了var
,感谢iLife捕获了当前值。尝试let
而不是var
,您会感到惊讶