I found an answer:
Javascript 1.7 and above supports block-level scope, and Firefox 3.0 and above supports it. (See http://en.wikipedia.org/wiki/Javascript#Versions )
I tried the following code using Firefox 3.5.9:
Note that the keyword let
is used, which will create a block-level scope.
<a href="#" id="link1">ha link 1</a>
<a href="#" id="link2">ha link 2</a>
<a href="#" id="link3">ha link 3</a>
<a href="#" id="link4">ha link 4</a>
<a href="#" id="link5">ha link 5</a>
<script type="application/javascript;version=1.7"/>
for (i = 1; i <=5; i++) {
let x = i;
document.getElementById('link' + i).onclick = function() { alert(x); return false; }
}
</script>
Sure enough, a new scope is created, with a new x
in it. The anonymous function that does the alert(x)
captures this scope (the whole scope chain) and remembers it, thus forming the closure. When this anonymous function is invoked, the scope is there, and when it looks for x
, sure enough, the x
is in that scope as 1, 2, 3, 4, 5 respectively. Try and change the let
into a var
and you get the infamous old problem again, because no new scope is created.