Javascript:循环遍历数组以创建侦听器,通过引用和值调用发出问题

Javascript: Looping through an array to create listeners, issue with call by reference and value?

本文关键字:引用 值调用 出问题 侦听器 循环 遍历 数组 创建 Javascript      更新时间:2023-09-26
for (var i=0; i<layerCount; i++){
    for (var j=0; j<layerData[i].data.length; j++){
        var text = layerData[i].data[j].text;
        var latlng = new google.maps.LatLng(layerData[i].data[j].lat, layerData[i].data[j].lng);
        var marker = new google.maps.Marker({map: map, position: latlng});
        var infowindow = new google.maps.InfoWindow({content: text});
        google.maps.event.addListener(marker, 'click', function() {infowindow.open(map,marker);});
    }
}

上面代码中的问题很可能出在以 google.maps.event.addListener 开头的行中。无论我单击哪个标记,我都会为layerdata[i].data[j]数据字段中的最后一项打开一个信息窗口。似乎我是通过引用而不是按值调用的,因此所有侦听器的infowindowmarker是数组中的最后一项。

但是我该如何解决这个问题呢?

非常感谢!

你必须创建一个闭包:

for (var i=0; i<layerCount; i++){
    for (var j=0; j<layerData[i].data.length; j++){
        var text = layerData[i].data[j].text;
        var latlng = new google.maps.LatLng(layerData[i].data[j].lat, layerData[i].data[j].lng);
        var marker = new google.maps.Marker({map: map, position: latlng});
        var infowindow = new google.maps.InfoWindow({content: text});
        bindOpenWindow(infowindow, map, marker);
    }
}
function bindOpenWindow(infowindow, map, marker)
{
    google.maps.event.addListener(marker, 'click', function() {infowindow.open(map, marker);});
}

看看它是否有助于;)

JavaScript没有

块作用域的概念,只有函数和全局作用域。您可以使用闭包来解决它:

for (var i = 0; i < layerCount; i++){
    for (var j = 0; j < layerData[i].data.length; j++){
        var text = layerData[i].data[j].text;
        var latlng = new google.maps.LatLng(layerData[i].data[j].lat, layerData[i].data[j].lng);
        var marker = new google.maps.Marker({map: map, position: latlng});
        var infowindow = new google.maps.InfoWindow({content: text});
        google.maps.event.addListener(marker, 'click', (function(infowindow, marker) {
            return function() {infowindow.open(map, marker);};
        })(infowindow, marker));
    }
}