[英]Return a function from the anonymous wrapper?
我试图理解代码
for(var i = 0; i < 10; i++) {
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
}
从这里http://bonsaiden.github.com/JavaScript-Garden/#function.closures
我理解这种方法:
for(var i = 0; i < 10; i++) {
(function(e) {
setTimeout(function() {
console.log(e);
}, 1000);
})(i);
}
任何人都可以通过解释第一个来帮助我吗?
我将尝试解释我如何理解第一个,
first i is 0,
setTimeout is called,
self calling function "function(e)" is called with i=0,
Im stuck!! what happens when this function returns a function?
所有第一个返回的函数将在超时发生后调用。
它的目的是为for循环的每次迭代创建一个子范围,以便在每次迭代时不会覆盖递增i
。
更多解释:
让我们把它分成两个不同的部分:
for(var i = 0; i < 10; i++) {
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
}
这是第一篇:
for(var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i); //9-9
},1000);
}
现在,当你运行这个循环时,你将总是得到包含9而不是0到9的console.log()。这是因为每个setTimeout都使用与i
相同的引用。
如果将setTimeout的一部分包装在匿名函数中,它会为每次迭代创建一个范围,允许每个setTimeout拥有它自己的i
值。
for(var i = 0; i < 10; i++) {
setTimeout((function(i) {
return function() {
console.log(i); // 0-9
}
})(i), 1000)
}
setTimeout中的外部函数立即执行,第一次迭代的i为0,第二次为1,等等。然后该函数返回一个函数,该函数是setTimeout使用的函数。 正在使用i
的不同值为循环的每次迭代生成并返回函数。
两者都得到相同的结果:使用要调用的函数调用setTimeout,该函数在控制台上写入0到9之间的数字。 两者都使用嵌套函数将i的当前值放入闭包中,因此最终不会记录10 9。
第一个代码选择让函数返回setTimeout将调用的函数。 第二个更改嵌套顺序,以便关闭函数调用setTimeout本身。 净效果是一样的。
除了风格和个人选择之外,我没有理由选择其中一个。
“你可以查看更新的问题,指明我在哪里感到困惑”
好的,这是一个很长的解释。 请记住, setTimeout()
的第一个参数需要是对指定延迟后要执行的函数的引用。 最简单的情况是命名一个在别处定义的函数:
function someFunc() {
console.log("In someFunc");
}
setTimeout(someFunc, 100);
注意someFunc
在将其作为参数传递给setTimeout
时没有括号,因为需要对函数本身的引用。 对比:
setTimeout(someFunc(), 100); // won't work for someFunc() as defined above
使用括号,它调用 someFunc()
并将其返回值传递给setTimeout
。 但是我对someFunc()
定义并没有明确地返回一个值,所以它隐式返回undefined
- 就像说setTimeout(undefined, 100)
。
但是如果更改someFunc()
以返回函数而不是返回undefined
,它将起作用:
function someFunc() {
return function() {
console.log("In the function returned from someFunc");
};
}
所以现在(最后)我们来看你问题的代码:
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
它不是通过名称引用函数并将其称为someFunc(i)
而是定义一个匿名函数并立即将其作为(function(e) {})(i)
调用。 该匿名函数返回另一个函数,它返回的函数成为setTimeout()
的实际参数。 当时间到时,它将返回将要执行的函数。 因为返回的(内部)函数是在(外部)匿名函数的范围内定义的,所以它可以访问e
参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.