Emre Sevinc wrote:
function add(elementId) {
var container = document.getElementById(elementId);
for (var i = 0; i < 10; i++) {
var elt = document.createElement('div');
elt.innerHTML = "" + i;
// Beware!
elt.onclick = function () {window.alert("" + i);};
container.appendChild(elt);
}
}
Now, when you click on the DIV element it produces and adds 10
DIV elements. That's okay but when you click on the child DIVs,
alert gives you 10. Not that you click on the first one and
you get 0 and the next one and 1, etc.
Why does that anonymous function always show the value of 10?
Well your subject names the reason, closures. (There are no higher order
functions (functions taking functions as arguments) however, not sure
why your subject names them too).
As for the closure, those anynymous functions you defined as the onclick
event handler are inner functions of the function add in which the
variable i is declared. When add is called and executed, that variable i
is incremented from 0 to 10 and the last value is what is available in
the closure to those inner functions as they are executed after the add
call is finished. If you executed an onclick handler during the add call
then of course the current value of i is what is accessed e.g.
function add() {
var container = document.body;
for (var i = 0; i < 10; i++) {
var elt = document.createElement('div');
elt.appendChild(document.createTextNode(i));
elt.onclick = function () {window.alert("" + i);};
container.appendChild(elt);
if (i == 5) {
elt.onclick();
}
}
}
add();
And i can be changed by those inner functions during the execution of
add and after add has been finished:
function add() {
var container = document.body;
for (var i = 0; i < 10; i++) {
var elt = document.createElement('div');
elt.appendChild(document.createTextNode(i));
elt.onclick = function () { alert(++i); };
container.appendChild(elt);
if (i == 5) {
elt.onclick();
}
}
}
add();
Check the FAQ notes on closures:
<http://www.jibbering.com/faq/faq_notes/closures.html>
If you want to have an onclick handler that uses the i value that i has
during the creation of the event handler then a function constructed
with new Function e.g.
elt.onclick = new Function("evt", "alert(" + i + ");");
is one way.
--
Martin Honnen
http://JavaScript.FAQTs.com/