谜题:闭包中的值发生了变化

发布于 2024-09-19 21:36:29 字数 868 浏览 3 评论 0原文

我使用 http://tile.cloudmade.com/wml/latest/web-maps-lite.js 进行地理编码。

有一个包含大约 20 个地址的地址数组

addresses[n] = {where:where,who:who,contact:contact,note:note,type:type};

然后我循环该数组进行地理编码

for (var i = 0; i < addresses.length; i++) {
    geocoder2.getLocations(addresses[i].where, function(response) { //a callback
       return function(k){
       Lat[k] = response.features[0].centroid.coordinates[0];
       Lng[k] = response.features[0].centroid.coordinates[1];
       latlng = new google.maps.LatLng(Lat[k], Lng[k]);
        MarkerArray[k] = new google.maps.Marker({
          map: map,
          position: latlng,
          zIndex: k,
          title: addresses[k].who,
          icon: icons(addresses[k].type.trim())
        });}(i) // a closure function called
    });
}

但它始终适用于最终索引。为什么??

I use http://tile.cloudmade.com/wml/latest/web-maps-lite.js to geocode.

There is a address array containing around 20 addresess

addresses[n] = {where:where,who:who,contact:contact,note:note,type:type};

Then I loop the array to geocode

for (var i = 0; i < addresses.length; i++) {
    geocoder2.getLocations(addresses[i].where, function(response) { //a callback
       return function(k){
       Lat[k] = response.features[0].centroid.coordinates[0];
       Lng[k] = response.features[0].centroid.coordinates[1];
       latlng = new google.maps.LatLng(Lat[k], Lng[k]);
        MarkerArray[k] = new google.maps.Marker({
          map: map,
          position: latlng,
          zIndex: k,
          title: addresses[k].who,
          icon: icons(addresses[k].type.trim())
        });}(i) // a closure function called
    });
}

But the it always works on the final index. Why??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆梦 2024-09-26 21:36:29

您遇到了闭环问题。您似乎试图通过添加 return function(k)... 闭包来修复它,但这全部发生在回调函数内部,因此直到循环退出并且 < code>i 指向其最终值。

您必须将该包装器推出一个级别,以便它直接位于循环内部:

for (var i = 0; i < addresses.length; i++) {
    geocoder2.getLocations(addresses[i].where, function(k) { //a callback
        return function(response){
            Lat[k] = response.features[0].centroid.coordinates[0];
            Lng[k] = response.features[0].centroid.coordinates[1];
            latlng = new google.maps.LatLng(Lat[k], Lng[k]);
            MarkerArray[k] = new google.maps.Marker({
                map: map,
                position: latlng,
                zIndex: k,
                title: addresses[k].who,
                icon: icons(addresses[k].type.trim())
            });
        }
    }(i)); // binding *here* instead!
}

或者使用 Function#bind 以避免嵌套函数。

You have the Closure Loop Problem. You appear to be trying to fix it by adding the return function(k)... closure, but that's all occurring inside the callback function, so it won't execute until the loop has exited and i is pointing at its final value.

You would have to push that wrapper out a level so it's directly inside the loop:

for (var i = 0; i < addresses.length; i++) {
    geocoder2.getLocations(addresses[i].where, function(k) { //a callback
        return function(response){
            Lat[k] = response.features[0].centroid.coordinates[0];
            Lng[k] = response.features[0].centroid.coordinates[1];
            latlng = new google.maps.LatLng(Lat[k], Lng[k]);
            MarkerArray[k] = new google.maps.Marker({
                map: map,
                position: latlng,
                zIndex: k,
                title: addresses[k].who,
                icon: icons(addresses[k].type.trim())
            });
        }
    }(i)); // binding *here* instead!
}

Or use Function#bind to avoid the nested function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文