1

I searched but couldn't find an answer to this seemingly easy question, so...

Suppose I have a loop in which I need to set callbacks. My callback function looks like this:

function callback(var1) { // code }

Now my loop is something like this:

for( //condition)
{
 var x = something_different_each_time;
 document.getElementById('foo').addEventListener('click', function() { callback(x); }, false);
}

Now it looks like even if the loop runs n times, the anonymous function is compiled only once -- and hence every invocation of callback is called with the same argument (even though x varies in the loop every time).

I must be missing something here.. any help is greatly appreciated! :)

Anurag
142k37 gold badges223 silver badges262 bronze badges
asked May 21, 2010 at 7:41
10

4 Answers 4

2

The problem is that the block of the for statement doesn't creates a new scope, for that, the x variable belongs to its enclosing scope, and all anonymous functions refer to the same variable...

Use another function to create a new lexical environment to hold the value of x on each iteration:

for(/*condition*/) {
 var x = something_different_each_time;
 document.getElementById('foo').addEventListener('click', function () {
 return function(y) {
 callback(y);
 };
 }(x), false);
}
answered May 21, 2010 at 7:51
Sign up to request clarification or add additional context in comments.

3 Comments

I think you're missing some braces around your anonymous function expression there.
@deceze: Nope, the parentheses are required only when the function is on a place where it can cause a grammatical ambiguity between a function expression and a function declaration, in this case, the function is in the arguments list of a function call, it's clearly on expression context, no ambiguity... e.g.: (function (fn) { fn();})( function () {alert ('hi');} );
@deceze: maybe a better example: var foo = function () { return 'bar'; }(); the function is invoked without problems... foo === 'bar';
1

You should calculate x before calling your callback functin!

for( //condition)
{
 //var x = something_different_each_time;
 document.getElementById('foo').addEventListener('click', function() { 
 var x = something_different_each_time;
 callback(x); }, false);
}
answered May 21, 2010 at 7:48

1 Comment

This is not really the problem. Thanks anyway.
0

Yes, the x will refer to the same variable in the enclosing scope, and since the function is executing later, it'll have the last value of x. Try this:

.addEventListener(
 'click',
 (function (i) {
 return function () { callback(i); }
 })(x),
 false
);

This creates a closure with the current value of x locked inside.

answered May 21, 2010 at 7:54

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.