0

Here my intent is to iterate over an array of elements, and set an event handler on each element while also binding the current iterator value to that event handler. What I've come up with is:

for (var i = 0; i < elementArray.length; ++i)
{
      var elem = elementArray[i];
      elem.onmouseover = function() { foo(i); }
}

function foo(index)
{
       alert(index);
}

Here I use a closure to bind i to foo. The problem is that when foo is actually invoked, i is always equal to elementArray.length, because of course, when foo is invoked i has already been incremented to the maximum value. What I want here, I think, is for a new copy of i to be bound to each anonymous function, so that it passes the correct value to foo. But I'm not sure what the best way to do this is.

1
  • 1
    No, you don't use a closure, or at least not enough of them :-) The { } of the for loop do not create a new variable scope. The only thing that does that in JavaScript is a function. Commented Feb 22, 2012 at 17:08

2 Answers 2

1

This isn't working for you because by the time the mouseover handler is invoked, the value of i has changed, it is equal to elementArray.length. What you should do instead is return a function which creates a closure and holds the value of i at the time it is defined.

for (var i = 0; i < elementArray.length; ++i)
{
      var elem = elementArray[i];
      elem.onmouseover = foo(i);
}

function foo(index)
{
    return function(){
       alert(index);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can use Function.prototype.bind (or define one for the browsers that do not support it) to avoid (explicit) closures. Then your calls would be written as:

elem.onmouseover = function(x) { foo(x); }.bind(this, i); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.