使用JavaScript闭包将参数附加到匿名函数中的默认参数

5
我希望在循环运行Google地理编码器API时添加一些额外的参数,但我不确定如何将闭包参数附加到其匿名函数中,该匿名函数已经具有通过对API的调用传递的默认参数。
例如:
for(var i = 0; i < 5; i++) {
     geocoder.geocode({'address': address}, function(results, status) {
         // Geocoder stuff here
     });
}

我希望能够在传递给geocoder.geocode()匿名函数的代码块中使用i的值。但是,如果我在第4行使用闭包 }(i)); ,那么它将替换第一个参数并破坏geocoder。

是否有办法使用闭包或者以其他方式将i的值传递到匿名函数中呢?

实际上,我想要做的是:

geocoder.geocode({'address': address}, function(results, status, i) {
    alert(i); // 0, 1, 2, 3, 4
}(i));

但是正在工作 :-)

2个回答

11

您可以通过闭包直接访问i,但需要捕获它以便每次调用geocode都会获取自己的副本。在JavaScript中,像往常一样,添加另一个函数就可以解决问题。我将外部的i变量重命名以使其更清晰:

for(var iter = 0; iter < 5; iter++) {
    (function(i) {
        geocoder.geocode({'address': address}, function(results, status) {
            // Geocoder stuff here
            // you can freely access i here
        });
    })(iter);
}

一个更简单的解决方案!早该发帖了。 - WheresWardy
1
我本来想说,在外部作用域和内部作用域中都有i很容易造成困惑,但是我看到你已经修复了这个问题,所以我就放过你了 :) - Skilldrick
我建议这个例子是最好的,因为其他的(它们更简单)在我的情况下不起作用:在地理编码器回调函数内部的 i 始终是循环中的最后一个。我猜这取决于浏览器异步的本质。但是这个答案完美地解决了问题!+1! - Igor Deruga
1
我知道这已经很老了,但我想纠正@Igor关于作用域和闭包的假设。这与“浏览器的异步性质”无关,而是因为每个创建的匿名函数都对完全相同的作用域具有闭包;这意味着它们都引用同一个i,即一个数字。更多细节,请阅读《You Don't Know JS》的这一章 - user5670895
对我有用!谢谢! - catbadger

3
function geoOuter(i) {
    geocoder.geocode({'address': address}, function(results, status) {
         // Geocoder stuff here
         // This has access to i in the outer function, which will be bound to
         // a different value of i for each iteration of the loop
     });
}

for(var i = 0; i < 5; i++) {
    geoOuter(i);
}

干这事吧...

如此简单明了的答案。非常感谢 :-) - WheresWardy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接