Javascript 无法理解闭包详细信息-for循环中的setTimeout
我很难理解为什么下面的第一个代码段快速执行所有五个Javascript 无法理解闭包详细信息-for循环中的setTimeout,javascript,Javascript,我很难理解为什么下面的第一个代码段快速执行所有五个console.log,而第二个代码段每隔一秒钟执行console.log 我知道在for循环的各个点上,需要一个闭包(也称为函数+声明它的范围)来“关闭”I的值 我知道在第一个代码段中,最里面的函数会被立即调用,而第二个代码段最里面的函数不会被立即调用 然而,我并不清楚到底发生了什么 一些问题: 在第一个代码段中,最里面的函数是否在单独的记号上执行 在第一个代码段中,为什么最里面的函数执行得这么快 在第二个代码段中,为什么最里面的函数执行间隔
console.log
,而第二个代码段每隔一秒钟执行console.log
我知道在for
循环的各个点上,需要一个闭包(也称为函数+声明它的范围)来“关闭”I
的值
我知道在第一个代码段中,最里面的函数会被立即调用,而第二个代码段最里面的函数不会被立即调用
然而,我并不清楚到底发生了什么
一些问题:
- 在第一个代码段中,最里面的函数是否在单独的记号上执行
- 在第一个代码段中,为什么最里面的函数执行得这么快
- 在第二个代码段中,为什么最里面的函数执行间隔超过1秒
for(var i=1;i这里的区别不在于闭包如何工作,而在于setTimeoute()
如何工作。setTimeout
将在传入时间后的某个时间调用传入函数。因此,您可以向其传递一个函数:
setTimeout(someFunction, 1000)
在1000毫秒左右的时间内,它执行someFunction()
在第一个示例中,在setTimout
有机会立即调用someFunction()之前,您正在执行函数
。当setTimeout
开始运行时,它没有要调用的函数——只有您已经调用的函数的返回值。这些函数将在当前时间同步调用
您可以将其视为传递回调。如果您将回调传递给像这样的函数someFunction(null,cb)
,它可以稍后使用cb()
执行它,但是如果您传递someFunction(null,cb())
,它将接收cb的返回值,而不是cb本身。如果这是一个函数,它将调用它
在第二个示例中,您立即执行外部函数,但返回一个函数,setTimeout
可以稍后调用。这就是它所做的,这就是为什么它会像预期的那样工作。它很简单,但很棘手:)
在第一个示例中,创建和执行匿名函数。然后返回未定义的setTimeout。setTimeout将不执行任何操作。这就是它执行速度快的原因
在第二个示例中,您创建并执行一个匿名函数,该匿名函数创建另一个匿名函数并将其返回到setTimeout。然后setTimeout将执行它
见我的评论:
for (var i = 1; i <= 5; i++) {
setTimeout(
(function (x) {
(function () {
console.log(x)
})(i) -> create and EXECUTE anonymous function (execute it right away)
})(i), -> create and execute anonymous function. returns undefined
i * 1000
)
}
for (var i = 1; i <= 5; i++) {
setTimeout(
(function (x) {
return (function () {
console.log(x)
})
})(i), -> create and execute anonymous function. returns a new function
i * 1000
)
}
for(var i=1;我创建并执行匿名函数(立即执行)
})(i) ,->创建并执行匿名函数。返回未定义的
i*1000
)
}
对于(var i=1;我创建并执行匿名函数。返回一个新函数
i*1000
)
}
这与闭包的机制无关。这100%是由函数的工作方式引起的
现在,让我们梳理一下这两个不同的函数。为了清晰起见,我将完全删除For循环:
1:
注意:请记住a()
返回未定义的。所以setTimeout实际上是:
setTimeout(undefined,1000);
“Helpfully”,如果您将undefined传递给setTimeout
,它将优雅地接受它,并且不会产生任何错误
显然,在调用a()
时直接调用console.log
现在让我们看看其他代码:
2:
var i=1;
功能b(x){
返回(函数(){
console.log(x)
})//好吧,你有3个正确答案,用3种不同的方式解释同一件事:)
setTimeout(undefined,1000);
var i = 1;
function b (x) {
return (function () {
console.log(x)
}) // <--- note you are not calling the inner function at all
}
setTimeout(b(i), i * 1000);