带有 Javascript 回调的闭包
Closures with Javascript callbacks
我以为我很好地理解了Javascript的闭包,但显然我不是。 以下代码不起作用。 如何让它在 1 秒延迟后在控制台中打印出从 0 到 9 的所有数字? 目前,它只打印"未定义"十次。
注意:我不是在寻找更简单的锻炼来延迟后打印数字。 这个问题是关于理解闭包的。
<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>
,并且您不必创建另一层嵌套。
这就是你的做法。创建一个 IIFE(立即调用的函数表达式(,该表达式返回打印到控制台的函数。记住 i 的值,应该被内部函数吞噬,通过将其作为参数传递。
setTimeout 期望一个"函数"作为第一个参数,这就是我们从 IIFE 返回函数的原因。
for(var i=0;i<10;i++){
setTimeout((function(i) {
return function() {
console.log(i);
}
})(i), 1000)
}
谢谢
您已经定义了回调函数来获取参数 i
,该参数屏蔽了在 for 循环中声明的可关闭i
。因此,请将其更改为:
<script>
for(var i=0;i<10;i++){
setTimeout(function(){console.log(i)}, 1000)
}
</script>
编辑:对不起,我没有看你问题的总体意图。就闭包的工作方式而言,函数对象捕获对封闭作用域中任何变量的引用,该变量从函数体内部引用,并且不绑定到主体内的任何局部变量(参数或显式var
声明(。这就是为什么你最初的尝试没有奏效;i
绑定到本地参数。
对象不捕获闭包变量在定义函数时拥有的值;它捕获对它的引用。因此,您不能迭代单个变量(我说的是 for 循环中声明的var i
(,目的是为每个后续函数定义关闭该值。值未关闭;变量是。
但是,您可以通过关闭具有定义函数时要捕获的值的临时局部区域来有效地关闭值。它需要创建一个新的函数作用域并在该作用域内定义闭合函数,围绕具有所需值的局部(函数参数(闭合:
<script>
for (var i_outer = 0; i_outer < 10; ++i_outer)
setTimeout((function(i_inner) { return function() { console.log(i_inner); }; })(i_outer), 1000 );
</script>
- javascript,将参数传递给函数内部的闭包中的回调
- JavaScript闭包&回调函数
- 使用闭包/函数绑定将自函数作为回调传递
- 使用JavaScript回调函数了解变量作用域和闭包
- 带有 Javascript 回调的闭包
- 非常基本的JavaScript回调/闭包结构
- 闭包的意外行为:回调保存最后一个值
- 尝试使用带有参数的闭包作为回调
- 对闭包变量的更改是否在使用闭包的回调中可见
- 创建带有回调的动态 JSON 数组(内部闭包问题)
- Is回调函数始终是一个闭包
- Javascript闭包:Phonegap和'这'在回调中
- 参数对应关系:回调与闭包(?)
- 回调中的闭包
- 我需要在DOM事件回调中使用闭包吗
- 使用Google闭包编译器记录回调参数
- 作为闭包的回调中的Javascript变量作用域
- JS闭包——依赖回调的多个日期选择器初始化/调用
- 闭包回调中参数的作用域
- 循环中的闭包/回调