2

我正在使用 Google Maps API 在地图上绘制几个点。但是,在下面的点击事件函数中,i总是设置为4,即循环迭代后的值:

// note these are actual addresses in the real page
var addresses = new Array( "addr 1", "addr 2", "addr 3", "addr 4" );

for (var i = 0; i < addresses.length; i++) {
    geocoder.getLatLng(addresses[i], function(point) {
        if (point) {
            var marker = new GMarker(point);
            map.addOverlay(marker);
            map.setCenter(point, 13);

            GEvent.addListener(marker, "click", function() {
                // here, i=4
                marker.openInfoWindowHtml("Address: <b>" + addresses[i] + "</b>");
            });
        }
    });
}

因此,当标记显示时,它使用addresses[4]的是未定义的。如何将正确的值传递i给函数?

4

2 回答 2

1

您需要在当前迭代期间生成一个匿名函数,以下应该修复它:

// note these are actual addresses in the real page 
var addresses = new Array( "addr 1", "addr 2", "addr 3", "addr 4" ); 

for (var i = 0; i < addresses.length; i++) { 
    geocoder.getLatLng(addresses[i], function (current) { 
        return function(point) { 
            if (point) { 
                var marker = new GMarker(point); 
                map.addOverlay(marker); 
                map.setCenter(point, 13); 

                GEvent.addListener(marker, "click", function() { 
                    // here, i=4 
                    marker.openInfoWindowHtml("Address: <b>" + addresses[current] + "</b>"); 
                }); 
            }
        } 
    }(i)); 
} 

B// 注意这些是实际页面中的实际地址 var addresses = new Array( "addr 1", "addr 2", "addr 3", "addr 4" );

for (var i = 0; i <addresses.length; i++) { geocoder.getLatLng(addresses[i], function(point) { if (point) { var marker = new GMarker(point); map.addOverlay(marker) ; map.setCenter(point, 13);

        GEvent.addListener(marker, "click", function() { 
            // here, i=4 
            marker.openInfoWindowHtml("Address: <b>" + addresses[i] + "</b>"); 
        }); 
    } 
}); 

}

进一步
说明 Google 提供 的getLatLng方法使用 ajax 调用来获取特定地址的 lat 和 long。由于这是一个异步调用并且不是当前线程的一部分,因此需要一个回调函数,该函数在 ajax 请求完成时调用。这是您指定为函数的第二个参数的匿名函数。
现在,在发出 ajax 请求的同时,您的代码继续运行,i每次循环遍历数组时都会增加值。当您的第一个 ajax 调用返回时,循环已经增加到地址数组 (4) 的长度,因此当您的回调函数运行时,您将在i循环增加后检索范围内变量。

使用我编写的修复程序,您将创建一个匿名函数,该函数接受一个参数 - current- 并返回前一个匿名函数,其中i变量替换为current变量。在循环的下一次迭代之前立即调用此函数,并将i变量作为它的第一个参数。这将创建一个闭包,在调用函数时,该闭包的当前值i存储在current变量中。当我们稍后引用该current变量时,我们将获得i.

我不是很擅长解释这类事情,可能是因为我对它的理解不如js大神。最好阅读有关 javascript 闭包的更多信息

于 2010-01-19T18:25:27.233 回答
-1

我不应该在那个循环中达到 4。只要 i <addresses.length(即 4),循环就会运行,因此循环应该从 i=0 运行到 i=3。

于 2010-01-19T18:25:26.187 回答