Yes, you can, but that won't work for the example you provided. You would be having a very common closure problem in that for
loop.
Variables enclosed in a closure share the same single environment, so by the time the onclick
callback is called, the for
loop will have run its course, and the i
variable will be left pointing to the last value it was assigned. In your example, the do_something_very_important()
function will be passed the value 100
for each node, which is not what you intend.
You can solve this problem with even more closures, using a function factory:
function makeClickHandler(i) {
return function() {
do_something_very_important(i);
};
}
// ...
for(var i = 0; i < 100; i++) {
get_node(i).onclick = makeClickHandler(i);
}
This can be quite a tricky topic, if you are not familiar with how closures work. You may want to check out the following Mozilla article for a brief introduction:
UPDATE:
You could also inline the above function factory as @adamse suggested in the other answer. This is actually a more common approach, but is practically the same as the above:
for(var i = 0; i < 100; i++) {
get_node(i).onclick = (function(p) {
return function () {
// we could have used i as a parameter variable as well,
// but we're using p to better illustrate what's happening
do_something_very_important(p);
}
})(i);
}
Any yet another solution is to enclose each iteration in its own scope, by using self invoking anonymous functions:
for(var i = 0; i < 100; i++) {
(function (p) {
// we now have a separate closure environment for each
// iteration of the loop
get_node(i).onclick = function() {
do_something_very_important(p);
}
})(i);
}