我知道使用此代码将0到9记录的方法之一:
编辑: http://localhost:4000/sesnors_home/John
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}), 10)
}
是让setTimeout
自我调用并将i
作为参数传递,如下所示:
for(var i = 0; i < 10; i++) {
setTimeout((function(i) {
console.log(i);
})(i), 10)
}
但是我已经测试了setTImeout
自我调用而没有通过i
,它仍然有效:
for(var i = 0; i < 10; i++) {
setTimeout((function() {
console.log(i);
})(), 10)
}
我的问题:
i
作为参数传递也能正常工作?i
?答案 0 :(得分:8)
这不是关闭。
for(var i = 0; i < 10; i++) {
setTimeout((function(i) {
console.log(i);
})(i), 10)
}
setTimeout实际上需要一个函数作为参数,但是你让它立即调用。因此,它会立即记录i
的值,而无需等待。 setTimeout现在返回您的匿名函数作为第一个参数undefined
。
同样在这里:
for(var i = 0; i < 10; i++) {
setTimeout((function() {
console.log(i);
})(), 10)
}
它立即执行,不等待10ms。您没有将i
作为参数传递给唯一的区别,但它会在父范围内查找名为i
的变量 - 并且只有一个。
如果您将时间设置为例如,您将看到立即调用您的匿名函数一秒钟(1000
)。
真正的关闭看起来像这样:
没有参数:你会看到10次10,因为在执行内部函数时循环已经完成,这意味着当时我等于10:
for(var i = 0; i < 10; i++) {
(function() {
setTimeout(function() {
console.log(i);
},10);
})();
}
使用参数 - 您将获得预期结果:
for(var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
},10);
})(i);
}
答案 1 :(得分:3)
在所有的avobe代码中,您正在执行setTimeout中作为第一个参数给出的函数而不返回任何内容。那么你要回来的是undefined
。
在下面的代码中,我也是自我调用的,但返回一个函数,使setTimeout在特定的时间间隔i * 10
之后执行。
这是闭包功能。检查控制台日志。它以毫秒为单位打印时间戳。差距为10毫秒。
for (var i = 0; i < 10; i++) {
setTimeout((function(i) {
return function() {
console.log(i, performance.now() + 'ms');
}
})(i), i * 10)
}
其他信息 在评论部分,我有一个查询
什么是重点,当你可以把setTimeout放在一个匿名函数中? 所以我猜这是你建议的代码。
for (var i = 0; i < 10; i++) { setTimeout(function() { console.log(i, performance.now() + 'ms'); }, i * 10) }
如果您运行此代码段,则每个日志的日志都会为10。这就是封闭之美。当您执行匿名函数
时function() {
console.log(i, performance.now() + 'ms');
}
它无法在当前范围内找到i
并搜索其父范围。瞧,它找到了我,但不幸的是,循环已经完成了它的迭代,现在它的值= 10。所以每次记录10次。
这就是我们需要关闭的原因。