[英]Javascript: every event-handler defined in for-loop is the same, uses last iteration's values
我无法理解 Javascript 中的范围规则。
在下面的示例中,我假设 scope url 变量在 for 循环中是私有的。 并且 onload-event function 会看到这个私有实例。
但事情似乎并非如此 - 警报将与最后一个 url 一起弹出两次。
如果有人能澄清发生了什么,我将不胜感激。
<html>
<head>
</head>
<body>
<script type="text/javascript">
var testArray = ["http://g0.gstatic.com/images/icons/onebox/weather_rain-40.png", "http://g0.gstatic.com/images/icons/onebox/weather_scatteredshowers-40.png"];
for (var i=0;i<testArray.length;i++){
var img = new Image();
var url = testArray[i];
img.onload = function(){
alert(url);
}
img.src = url;
}
</script>
</body>
</html>
JavaScript没有块范围。
创建新变量 scope 的唯一方法是在 function 中。
var testArray = ["http://g0.gstatic.com/images/icons/onebox/weather_rain-40.png", "http://g0.gstatic.com/images/icons/onebox/weather_scatteredshowers-40.png"];
function createImg( url ) {
var img = new Image();
img.onload = function(){
alert(url);
}
img.src = url;
return img;
}
for (var i=0;i<testArray.length;i++){
var img = createImg(testArray[i]);
}
将testArray[i]
传递给创建并返回新图像的 function 以确保在onload
处理程序中引用的url
将是 ZC1C425268E68385D1AB5074C 中的范围。
编辑:
最终,如果您只需要访问url
,您将永远不会这样做。
您只需通过this
从元素的属性中获取它。
function onloadHandler(){
alert( this.src ); // <--- get the url from the .src property!
}
var testArray = ["http://g0.gstatic.com/images/icons/onebox/weather_rain-40.png", "http://g0.gstatic.com/images/icons/onebox/weather_scatteredshowers-40.png"];
for (var i=0;i<testArray.length;i++){
var img = new Image();
var url = testArray[i];
img.onload = onloadHandler;
img.src = url;
}
这样,您就不会在循环中创建相同的处理程序 function 实例,而是共享相同的实例,并引用通过this
接收事件的元素。
Javascript 不是块范围的,因此每次您想要一个新的 scope 时都需要一个新的 function。 请参阅 patrick dw 的答案。
这就是为什么使用 javascript 标准中的[].map(function(x){...})
或[].forEach(function(x){...})
是有利的,因为您将无论如何都需要定义这些功能。
var imageArray = urlArray.map(function(url) {
var image = new Image();
image.src = url;
image.onload = function() {
alert(url);
};
return image;
});
尝试这个:)
var testArray = ["http://g0.gstatic.com/images/icons/onebox/weather_rain-40.png", "http://g0.gstatic.com/images/icons/onebox/weather_scatteredshowers-40.png"];
for (var i=0;i<testArray.length;i++){
var img = new Image();
var url = testArray[i];
img.onload = function(){
alert([img.src, url, i]);
}
img.src = url;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.