I have trouble understanding the scoping rules in Javascript.
In the example below, I would assume that scope url variable is private in the for-loop. And that the onload-event function would see this private instance.
But things does not seems work like that - the alert will popup with the last url twice.
If somebody can clarify what is going on, I'll 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>
Javascript is not block-scoped, and thus requires a new function every time you want a new scope. See the answer by patrick dw.
This is why it is advantageous to use
[].map(function(x){...})
or[].forEach(function(x){...})
which are in the javascript standard, since you'll need to define those functions anyway.JavaScript does not have block-scope.
The only way to create new variable scope is in a function.
Passing the
testArray[i]
to a function that creates and returns the new image ensure that theurl
referenced in theonload
handler will be the one that was scoped in the function.EDIT:
Ultimately, you'd never do this if all you need is access to the
url
.You'd just get it from the property of the element via
this
.This way you're not creating an identical handler function instance in the loop, but rather sharing the same instance, and referencing the element that received the event via
this
.Try this :)