首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript: for-loop中定义的每个事件处理程序都是相同的,使用上一次迭代的值

Javascript: for-loop中定义的每个事件处理程序都是相同的,使用上一次迭代的值
EN

Stack Overflow用户
提问于 2011-05-29 02:46:30
回答 3查看 590关注 0票数 3

我在理解Javascript中的作用域规则时遇到了问题。

在下面的示例中,我假设作用域url变量在for循环中是私有的。并且onload-event函数将看到这个私有实例。

但事情似乎并不是这样的-警报将弹出最后一个网址两次。

如果有人能弄清楚到底是怎么回事,我将不胜感激。

代码语言:javascript
复制
<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>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-29 03:08:40

Javascript不是块作用域,因此每次需要新作用域时都需要一个新函数。请参阅patrick dw的答案。

这就是为什么使用javascript标准中的[].map(function(x){...})[].forEach(function(x){...})是有利的,因为您无论如何都需要定义这些函数。

代码语言:javascript
复制
var imageArray = urlArray.map(function(url) {
    var image = new Image();
    image.src = url;
    image.onload = function() {
        alert(url);
    };

    return image;
});
票数 4
EN

Stack Overflow用户

发布于 2011-05-29 02:49:54

JavaScript没有块作用域。

创建新变量作用域的唯一方法是在函数中。

代码语言: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从元素的属性中获取它。

代码语言:javascript
复制
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接收事件的元素。

票数 7
EN

Stack Overflow用户

发布于 2011-05-29 02:55:12

试试这个:)

代码语言: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([img.src, url, i]);
    }
    img.src = url;
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6163720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档