Consider the following example:
function async_callback(array1, array2, array3) {
// All arrays are equal length
for(var i = 0; i < array1.length; i++) {
var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': { 'click': function() { SomeFunction(array1[i], array2[i], array3[i] } }});
$(document).appendChild(myElement);
}
}
Now when I click my element, I get a null value for all three arguments. I even tried doing:
myElement.onclick = SomeFunction; // but this won't allow arguments
I know I can create a string and use eval()
and that does work, but I don't like eval()
.
Any ideas?
BTW: This is a simple example to replicate the problem, and not actual code.
This is your handler:
function() { SomeFunction(array1[i], array2[i], array3[i] } }
By the time its executed, the loop will have completed and i
will therefore be equal to the length
of the array, as per the conditional statement (i < array1.length
) and the iteration statement (i++
).
The easiest way to resolve this is to wrap the handler in an additional immediately-executed function, and pass i
to it, -- this will have the effect of retaining the value of i
in a new closure:
for(var i = 0; i < array1.length; i++) {
var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': {
'click': (function(i){
return function() { SomeFunction(array1[i], array2[i], array3[i] } };
}(i))
});
$(document).appendChild(myElement);
}