我以为我很了解 Javascript 的闭包,但显然我没有。下面的代码不起作用。如何让它在 1 秒延迟后在控制台中打印出从 0 到 9 的所有数字?目前它只打印“undefined”十次。
注意:我并不是在寻找一种更简单的锻炼方法来在延迟后打印出数字。这个问题是关于理解闭包的。
<script>
for(var i=0;i<10;i++){
setTimeout(function(i){console.log(i)}, 1000)
}
</script>
最佳答案
闭包在 JavaScript 中很重要,但了解自己到底是什么也很重要 closing
超过。重写您当前的代码(某种程度)。
function(){
var i;
for(i=0;i<10;i++){
setTimeout(function(){
console.log(i);
}, 1000);
}
}
在此示例中,您的代码基本上结束于 var i;
,这意味着当定时器运行时,它会读取var i;
的值并将其打印出来。在这种情况下,正如您所看到的,当计时器运行时,循环已完成,并且值为10
。 .
您想要做的是创建一个新的函数作用域来捕获 i
的值在特定时间。
function(){
var i;
for(i=0;i<10;i++){
(function(iInner){
setTimeout(function(){
console.log(iInner);
}, 1000);
})(i);
}
}
这个例子将创建一个新的匿名函数,然后立即在循环中调用它,并传递i
的当前值。进入它,这样当你的计时器读取 iInner
时,它将读取传递给函数的值,而不是 var i;
中的值。 。您也可以调用iInner
i
如果您愿意,但为了清楚起见,我使用了两个不同的名称。
您还可以使用一些帮助程序,例如 .bind
这实际上会自动为您创建一个新的匿名函数,并传递这样的参数。
function(){
var i;
for(i=0;i<10;i++){
setTimeout(function(iInner){
console.log(iInner);
}.bind(null, i), 1000);
}
}
<func>.bind
将取值i
并返回一个新函数,将这些参数传递给 <func>
当调用时,您可以避免创建另一层嵌套。
关于javascript - 带有 Javascript 回调的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27336286/