JavaScript中,在FOR循环中循环时,如何将数组中项的值传递给匿名函数?

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循环来获取数组中某项的值,并将其传递给匿名函数。下面是一个简化的例子:

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] 而不是 aStrings[0].

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


为了提供更具体的细节,我正在处理 Google 地图页面,标记存储在 JavaScript 数组客户端和数据库服务器端。我在页面加载时编写数组,完成后我想生成标记,并为每个标记提供一个自定义信息窗口,并将文本设置为 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 字符串,而是获取用于所有标记的数组中最后一项的文本。

您可以在 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);
}

关于关闭的更多信息:

  • MDN
  • Whosebug how do closures work?

您需要使用闭包。在此处阅读更多相关信息: 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"

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/

好吧,您可以避免 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); });

}