Javascript:在for循环中定义的每个事件处理程序都是相同的,使用上次迭代的值
Javascript: every event-handler defined in for-loop is the same, uses last iteration's values
我很难理解Javascript中的范围规则。
在下面的示例中,我假设范围 url 变量在 for 循环中是私有的。并且加载事件函数将看到此私有实例。
但事情似乎并非如此 - 警报将两次弹出最后一个 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 没有块作用域。
创建新变量作用域的唯一方法是在函数中。
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]
传递给创建和返回新图像的函数可确保onload
处理程序中引用的url
将是函数中作用域
编辑:
最终,如果您只需要访问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;
}
这样,您就不会在循环中创建相同的处理程序函数实例,而是共享相同的实例,并引用通过 this
接收事件的元素。
Javascript 不是块作用域,因此每次需要新作用域时都需要一个新函数。请参阅帕特里克 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;
}
相关文章:
- 如何在javascript中迭代数字列表
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 如何迭代Array.prototype函数
- 如何使用jquery迭代具有相同属性的html元素并查找onclick事件
- 在ejs-partial中对JSON对象进行迭代
- 如何在DataTables 2.1中迭代对象数组
- JavaScript1.7区分数组和对象的迭代程序
- JavaScript迭代程序
- 使用 Node.jS 驱动程序在 MongoDB 中迭代多个集合并比较结果
- 在 Angular 项目中迭代 JSON 响应以创建新的 $scope obj 我可以在应用程序中使用的
- 谷歌应用程序电子表格脚本;t总是完成迭代,否则效果良好
- 闭包(JS)迭代程序
- 迭代摘要应用程序Rally SDK
- 如何设置class=“;活动的”;当使用迭代生成N个选项卡(引导程序)时
- 在Ionic中,如何在for循环的每次迭代后向应用程序视图添加数据
- 当我在jQuery应用程序中迭代javascript字典的键时,我得到的是数字而不是值
- 量角器:如何迭代和比较从应用程序和场景表使用中继器得到的值
- 如何在React应用程序中隔离和迭代各个React组件
- Javascript:在for循环中定义的每个事件处理程序都是相同的,使用上次迭代的值
- jQuery/JavaScript:仅在循环的最后一次迭代期间分配的事件处理程序