带有Javascript回调的闭包

带有Javascript回调的闭包,javascript,closures,Javascript,Closures,我以为我能很好地理解Javascript中的闭包,但显然我不懂。以下代码不起作用。我如何让它在1秒钟延迟后在控制台中打印出从0到9的所有数字?目前它只打印“未定义”十次 注意:我不是在寻找一个更简单的训练,在延迟后打印出数字。这个问题是关于理解闭包的 <script> for(var i=0;i<10;i++){ setTimeout(function(i){console.log(i)}, 1000) } </script> for(var i=0;i

我以为我能很好地理解Javascript中的闭包,但显然我不懂。以下代码不起作用。我如何让它在1秒钟延迟后在控制台中打印出从0到9的所有数字?目前它只打印“未定义”十次

注意:我不是在寻找一个更简单的训练,在延迟后打印出数字。这个问题是关于理解闭包的

<script>
for(var i=0;i<10;i++){
    setTimeout(function(i){console.log(i)}, 1000)
}
</script>


for(var i=0;i您已经定义了回调函数来获取参数
i
,它屏蔽了for循环中声明的可克隆
i
。因此将其更改为:

<script>
for(var i=0;i<10;i++){
    setTimeout(function(){console.log(i)}, 1000)
}
</script>

这就是方法。创建一个IIFE(立即调用的函数表达式),它返回一个打印到控制台的函数。记住i的值,应该作为参数传递给内部函数

setTimeout需要一个“函数”作为第一个参数,这就是我们从IIFE返回函数的原因

for(var i=0;i<10;i++){

    setTimeout((function(i) {
        return function() {
            console.log(i);
        }
    })(i), 1000)
}

for(var i=0;i闭包在JavaScript中很重要,但了解您到底在做什么是
闭包
很重要。要重新编写当前代码(某种)

本例将创建一个新的匿名函数,然后在循环中立即调用它,并将当前值
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);
    }
}
function(){
var i;

对于(i=0;不可用!只需打印
10
十次。这就是我们需要闭包的原因。
function(){
    var i;
    for(i=0;i<10;i++){
        setTimeout(function(){
            console.log(i);
        }, 1000);
    }
}
function(){
    var i;
    for(i=0;i<10;i++){
        (function(iInner){
            setTimeout(function(){
                console.log(iInner);
            }, 1000);
        })(i);
    }
}
function(){
    var i;
    for(i=0;i<10;i++){
        setTimeout(function(iInner){
            console.log(iInner);
        }.bind(null, i), 1000);
    }
}