简体   繁体   English

JS通过调用或不调用函数的反应不同(使用了Google Maps API)

[英]JS reacts differently by calling or not calling a function (google maps api is used)

I experienced strange behaviour by calling or not calling a separate function in JavaScript code. 通过调用或不调用JavaScript代码中的单独函数,我遇到了奇怪的行为。 I am not able to comprehend the difference in result – from my point of view the exact same result should appear. 我无法理解结果的差异–从我的角度来看,应该出现完全相同的结果。

The following code is the working one. 以下代码是有效的代码。 It sets the InfoWindow onto the markers and the links. 它将InfoWindow设置到标记和链接上。

for (loc in alleDaten) {
        place = alleDaten[loc];
        place['marker'] = new google.maps.Marker({position:place.pos, icon:'marker2.png'});
        place.marker.setMap(map);
        doEverything(place);
    }
    function doEverything(place) {
        google.maps.event.addListener(place.marker, 'click', function() {setInfowindow(place.text, place.marker);});
        $(place.link).click(function() {setInfowindow(place.text, place.marker);});
    }
    function setInfowindow(text, marker) {
        infowindow.setContent(text); 
        infowindow.open(map, marker);
    }

The following code is almost the same, only the function call is removed. 以下代码几乎相同,只是删除了函数调用。 But the result is different: only the last entry of alleDaten is set to all markers and all links. 但是结果却不同:仅将alleDaten的最后一个条目设置为所有标记和所有链接。

for (loc in alleDaten) {
    place = alleDaten[loc];
    place['marker'] = new google.maps.Marker({position:place.pos, icon:'marker2.png'});
    place.marker.setMap(map);
    google.maps.event.addListener(place.marker, 'click', function() {setInfowindow(place.text, place.marker);});
    $(place.link).click(function() {setInfowindow(place.text, place.marker);});
}
function setInfowindow(text, marker) {
    infowindow.setContent(text); 
    infowindow.open(map, marker);
}

Is there a reason for this behaviour? 有这种行为的原因吗?

The two work differently because you have async code that references a local variable place that is changed in the for loop before the async code runs in your second block of code. 两者的工作方式有所不同,因为您有一个异步代码引用了一个局部变量place ,该位置在for循环中已更改,然后异步代码在第二个代码块中运行。 When you pass the place variable to a function in the first block of code, that creates a closure that maintains that variable's value separately for each invocation of the function so the event handling callbacks will refer to the correct version of place in the first block of code. 当您将place变量传递给代码的第一块中的一个函数时,这将创建一个闭包,该闭包为该函数的每次调用分别维护该变量的值,因此事件处理回调将引用该代码的第一块中的place的正确版本。码。

Whereas, In your second block of code, the place variable that is referenced inside the two click handlers will have long since changed by the for loop before the click handler is called. 而在您的第二段代码中,两个点击处理程序内部引用的place变量将在调用点击处理程序之前由for循环更改很长时间。

Remember, your for loop will run to completion (thus place will have the last value in it) before any of your click handler callbacks are actually called. 请记住,在实际调用任何点击处理程序回调之前,您的for循环将运行完成(因此该place将具有最后一个值)。 This same type of mistake is very common with a for loop index too. 相同的错误类型在for循环索引中也很常见。 The general solution is to create a closure that captures that changing variable for each separate path through the loop. 通用解决方案是创建一个闭包,以捕获通过循环的每个单独路径的变化变量。 Passing it to a function as you've done in your first code block is one way to do that. 如您在第一个代码块中所做的那样,将其传递给函数是一种实现方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM