javascript - 带有 Javascript 回调的闭包

标签 javascript closures

我以为我很了解 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/

相关文章:

javascript - 无法在 JQuery 函数中使用动态变量

ios - 从 swift 调用 objective-C typedef block

closures - 在 coffeescript 中对私有(private)变量使用闭包

javascript - 如何创建照片网格,您可以将它们悬停在其中,它们就会变成其他照片?

javascript - JavaScript/jQuery 中的嵌套循环不起作用

Javascript删除不会触发Java后端

java - Groovy Closure 不检查所有者或委托(delegate)范围

Swift loadItem 关闭未运行

Typescript strictNull 检查和闭包

javascript - 你如何为桌面而不是移动设备制作 bootstrap nav 顶级按钮可点击链接?