1

I have code that looks like this:

for( var i=0; i<10; i++ ) {
   var someClickableObject = new Object();
   someClickableObject.index = i; 

   eventListenerFunction(someClickableObject, 'click', function() {
      alert(someClickableObject.index);
   });
}

So I am creating a bunch of clickable objects, giving each a property equal to the loop index, setting a click event on the object which alerts its index property.

I want each object to alert the index i in which it was created. Instead all the objects alert 9. I think this is because the event listener forms a closure over the object which gets redefined on each iteration.

Any ideas on how to solve this?

1 Answer 1

1

The problem is actually the opposite of what you wrote: all the functions share the same closure. (edit — after re-reading what you wrote, I'm not sure it's "opposite" of anything; the point is that all those little functions you pass to the "eventListenerFunction" will be sharing the same variable, "someClickableObject", so at the end of the loop they'll all refer to the one created on the last iteration!)

To fix it, you need to introduce another scope somehow:

eventListenerFunction(someClickableObject, 'click', (function(obj) {
  return function() {
    alert(obj.index);
  };
})(someClickableObject));

That introduces an anonymous function. That little function is called with the reference to your local variable, which has the effect of creating another scope. That function returns the function actually passed to that "eventListener" thing. It's got its own copy of "someClickableObject" now.

However, it's just a shallow copy. In your case, that's OK because you're creating a new object on every iteration. In practice, I've almost never had to worry about such a case; usually a shallow copy is all I need to worry about (because often it's just a counter, or a string-valued key, or something like that involved).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.