[Javascript] adding onclick event's with YUI

Nick Fitzsimons nick at nickfitz.co.uk
Wed Jul 18 12:00:48 CDT 2007


> The code above works as I expect, but in a loop through the list I use a
> counter variable in place of the hardcoded number above and every link
> when clicked alert()'s the last number in the loop (in this case 3). But
> if I do each of them manually it works fine.
>
> I've set up a test page which you can see in action and hopefully
> understand what I'm try to say here: <http://qurl.com/ts66b>
>
> I'm thinking it has something to do with scope, but I can't pindown the
> problem. Anyone have any ideas?

Hi Matt,

This is a common scoping problem to do with closures. Basically, when you
create your inner function within the loop, it forms a closure over the
variable in the outer code; what this means is that, when the function is
invoked at a later time, it can reference the variable in the outer
function.

The important point is that it is the _variable_ to which it has access,
not the _value_ the variable had when the closure was formed, and as the
variable was originally inside a loop which finished executing earlier,
the later attempt to examine it will find the value that was left in it at
the end of the loop. (Confusing, isn't it :-)

So, for example,

var functions = [];
for (var i = 0; i < 10; i++) {
   functions[i] = function() {
      alert(i);
   }
}
functions[0](); // alerts 10

will alert 10, as that is what "i" was set to by the time the loop
terminated.

A simple way around this is to use a function that returns a function:

function makeAlertFunction(index) {
   return function() {
      alert(index);
   }
}

var functions = [];
for (var i = 0; i < 10; i++) {
   functions[i] = makeAlertFunction(i);
}
functions[0](); // alerts 0

as each function created will then have a closure over its own copy of
"index", so that e.g.

functions[0]() // alerts 0
functions[7]() // alerts 7

will work as expected.

HTH,

Nick.
-- 
Nick Fitzsimons
http://www.nickfitz.co.uk/





More information about the Javascript mailing list