[英]In JavaScript, when looping through a FOR loop, how do I pass the value of the item in an array to an anonymous function?
In JavaScript, I need to loop through a for
loop to get the value of an item in an array, and pass this to an anonymous function. 在JavaScript中,我需要遍历
for
循环以获取数组中一项的值,并将其传递给匿名函数。 A simplified example of this is below: 下面是一个简化的示例:
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 can see why this is happening - the variable i
is being set to 2
when the loop exits, and then when I call aFunctions[0]()
, the function fires off and evaluates aStrings[i]
rather than aStrings[0]
. 我可以看到发生这种情况的原因-循环退出时变量
i
被设置为2
,然后当我调用aFunctions[0]()
,该函数触发并评估aStrings[i]
而不是aStrings[0]
。
What I want to know is how to get the value of aStrings[i]
returned within my for
loop, and not when it's executed. 我想知道的是如何获取在我的
for
循环中返回的aStrings[i]
的值,而不是在执行时。
To give more specific detail, I'm working on a Google Maps page, and the markers are stored in a JavaScript array client-side, and in a DB server-side. 为了提供更多具体细节,我正在Google Maps页面上工作,这些标记存储在JavaScript数组客户端和数据库服务器端。 I write the array at page-load and after that's complete I want to generate the markers, and give them each a custom InfoWindow with the text set to an HTML string.
我在页面加载时编写数组,完成后我要生成标记,并为每个标记提供一个自定义InfoWindow,并将文本设置为HTML字符串。 This is the specific code I use:
这是我使用的特定代码:
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); });
}
Instead of getting the HTML string of the specific marker, I get the text of the last item in the array used for all markers. 我没有获取特定标记的HTML字符串,而是获取了用于所有标记的数组中最后一项的文本。
You need to use closure. 您需要使用闭包。 Read More about this here: How do JavaScript closures work?
在此处阅读有关此内容的更多信息: JavaScript闭包如何工作?
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"
You can use a closure around the addListener part: 您可以在addListener部分周围使用闭包:
(function(text){
google.maps.event.addListener(marker, 'click', function () { ShowMarkerContentPopUp(this, text); });
})(text);
This creates a new scope and takes the text
variable as an argument. 这将创建一个新的作用域,并将
text
变量作为参数。 It means the text
inside the closure is protected from being changed outside of the closure. 这意味着保护闭包内部的
text
不会在闭包外部被更改。
The same can be done to solve your first example: 可以通过同样的方法解决您的第一个示例:
for (var i = 0; i < aStrings.length - 1; i++) {
(function(i){
aFunctions[i] = function () { alert(aStrings[i]); };
})(i);
}
More info on closures: 有关闭包的更多信息:
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"
Well, you can avoid needing to worry about closures
much and still achieve the necessary results. 好吧,您可以避免担心太多的
closures
,而仍然可以达到必要的结果。 It can be done by attaching each text
variable to its respective marker. 可以通过将每个
text
变量附加到其各自的标记来完成。 This way your anonymous function can call it using this.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); });
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.