Javascript: each event handler defined in the for-loop is the same, uses the latest iteration values

I find it hard to understand the scope rules in Javascript.

In the example below, I would assume that the url scope variable is private in the for-loop. And that the onload-event function will see this private instance.

But it doesn't seem like this: a warning will appear with the last URL twice.

If someone can clarify what is happening, I will be grateful.

<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>
+3
source share
3 answers

Javascript is not blocky and therefore requires a new function every time you want a new scope. See Answer patrick dw.

[].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

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] , , , url, onload, , .


EDIT:

, , , , - 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.

+7

Try the following :)

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
source

All Articles