Tuesday, 20 September 2016

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

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...