Sunday, 17 September 2017

loops - Doesn't JavaScript support closures with local variables?





I am very puzzled about this code:



var closures = [];
function create() {
for (var i = 0; i < 5; i++) {

closures[i] = function() {
alert("i = " + i);
};
}
}

function run() {
for (var i = 0; i < 5; i++) {
closures[i]();
}

}

create();
run();


From my understanding it should print 0,1,2,3,4 (isn't this the concept of closures?).



Instead it prints 5,5,5,5,5.




I tried Rhino and Firefox.



Could someone explain this behavior to me?
Thx in advance.


Answer



Fixed Jon's answer by adding an additional anonymous function:



function create() {
for (var i = 0; i < 5; i++) {
closures[i] = (function(tmp) {

return function() {
alert("i = " + tmp);
};
})(i);
}
}


The explanation is that JavaScript's scopes are function-level, not block-level, and creating a closure just means that the enclosing scope gets added to the lexical environment of the enclosed function.




After the loop terminates, the function-level variable i has the value 5, and that's what the inner function 'sees'.






As a side note: you should beware of unnecessary function object creation, espacially in loops; it's inefficient, and if DOM objects are involved, it's easy to create circular references and therefore introduce memory leaks in Internet Explorer.


No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...