In Javascript, I am sometimes too immerged in the idea that a function creates a new scope, that sometimes I even think the following anonymous function will create a new scope when it is being defined and assigned to onclick:
<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="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = function() { var x = i; alert(x); return false; }
}
</script>
but in fact, the anonymous function will create a new scope, that’s right, but ONLY when it is being invoked, is that so? So the x inside the anonymous function is not created, no new scope is created. When the function was later invoked, there is a new scope alright, but the i is in the outside scope, and the x gets its value, and it is all 6 anyways.
The following code will actually invoke a function and create a new scope and that’s why the x is a new local variable x in the brand new scope each time, and the invocation of the function when the link is clicked on will use the different x in the different scopes.
<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="text/javascript">
for (i = 1; i <= 5; i++) {
(function() {
var x = i;
document.getElementById('link' + i).onclick = function() { alert(x); return false; }
})(); // invoking it now!
}
</script>
If we take away the var in front of x, then it is a global x and so no local variable x is created in the new scope, and therefore, clicking on the links get all the same number, which is the value of the global x.
Update: the question is: we have to be careful when we analyze code, that a function will not create a scope when it is merely defined and assigned. It has to invoked. Is that so?
The Scope of a function is set when the function object is created, for example:
In the above example, the function is created inside the
withblock, there the current scope is being augmented, to introduce the object with thefooproperty to the scope chain.In your second example, happens the same, the
onclickhandler function is being created inside the auto-invoking anonymous function, which itself has created a new lexical scope.At the moment that function is auto-invoked on each loop iteration, the value of
iis captured into that scope in thexvariable, then theonclickhandler function is created inside that scope, and it will be able to resolve it.