【问题标题】:In JavaScript, when looping through a FOR loop, how do I pass the value of the item in an array to an anonymous function?在 JavaScript 中,当循环 FOR 循环时,如何将数组中项目的值传递给匿名函数?
【发布时间】:2025-12-25 07:55:16
【问题描述】:

在 JavaScript 中,我需要循环通过 for 循环来获取数组中项目的值,并将其传递给匿名函数。一个简化的例子如下:

var aFunctions = []; 
var aStrings = ["a","b","c"];
for (var i = 0; i < aStrings.length - 1; i++) {
    aFunctions[i] = function () { alert(aStrings[i]); };
}
aFunctions[0](); //alerts "c" instead of "a"

我知道为什么会发生这种情况 - 当循环退出时,变量 i 被设置为 2,然后当我调用 aFunctions[0]() 时,函数触发并计算 aStrings[i] 而不是 @987654327 @。

我想知道的是如何在我的for 循环中返回aStrings[i] 的值,而不是在执行时。


为了提供更具体的细节,我正在处理 Google Maps 页面,标记存储在 JavaScript 数组客户端和数据库服务器端。我在页面加载时编写数组,完成后我想生成标记,并为每个标记提供一个自定义 InfoWindow,并将文本设置为 HTML 字符串。这是我使用的具体代码:

for (var i = 0; i < tGoogleMarker.length - 1; i++) {
    var text = tGoogleMarker[i][4];
    var marker = new google.maps.Marker({
                        position: new google.maps.LatLng(tGoogleMarker[i][0], tGoogleMarker[i][1]),
                        map: map,
                        flat: false,
                        icon: tGoogleMarker[i][2],
                        shadow: tGoogleMarker[i][3]
                        });
    google.maps.event.addListener(marker, 'click', function () { ShowMarkerContentPopUp(this, text); });
}

我没有获取特定标记的 HTML 字符串,而是获取用于所有标记的数组中最后一项的文本。

【问题讨论】:

    标签: javascript google-maps anonymous-function pass-by-value


    【解决方案1】:

    好吧,您可以避免过多担心closures,并且仍然可以获得必要的结果。可以通过将每个 text 变量附加到其各自的标记来完成。这样你的匿名函数就可以使用this.text调用它

    for (var i = 0; i < tGoogleMarker.length - 1; i++) {
    var marker = new google.maps.Marker({
                        text: tGoogleMarker[i][4],
                        position: new google.maps.LatLng(tGoogleMarker[i][0], tGoogleMarker[i][1]),
                        map: map,
                        flat: false,
                        icon: tGoogleMarker[i][2],
                        shadow: tGoogleMarker[i][3]
                        });
    google.maps.event.addListener(marker, 'click', function () { ShowMarkerContentPopUp(this, this.text); });
    

    }

    【讨论】:

      【解决方案2】:
      var aFunctions = []; 
      var aStrings = ["a","b","c"];
      for (var i = 0; i < aStrings.length; i++) {
          aFunctions[i] =  (function(arg) { return function() { alert(arg); };})(aStrings[i]) ;
      }
      aFunctions[0](); // alerts "a"
      aFunctions[2](); // alerts "c"
      

      http://jsfiddle.net/dbtncehf/

      【讨论】:

        【解决方案3】:

        你需要使用闭包。在此处阅读有关此内容的更多信息: How do JavaScript closures work?

        var aFunctions = []; 
        var aStrings = ["a","b","c"];
        for (var i = 0; i < aStrings.length - 1; i++) {
            aFunctions[i] = (function(val){
              return function() {
                  alert(val)
              }
            })(aStrings[i]);
        }
        aFunctions[0](); //alerts "c" instead of "a"

        【讨论】:

          【解决方案4】:

          您可以在 addListener 部分周围使用闭包:

          (function(text){
              google.maps.event.addListener(marker, 'click', function () { ShowMarkerContentPopUp(this, text); });
          })(text);
          

          这将创建一个新范围并将text 变量作为参数。这意味着闭包内的text 受到保护,不会在闭包外被更改。

          同样可以解决你的第一个例子:

          for (var i = 0; i < aStrings.length - 1; i++) {
              (function(i){
                  aFunctions[i] = function () { alert(aStrings[i]); };
              })(i);
          }
          

          更多关于闭包的信息:

          【讨论】:

          • 完美,这个解决方案解决了我的问题 - 我感谢对我的 sn-ps 的响应以及指向良好 closure 参考页面的链接。