开发者

Javascript function question

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! :)


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);
}


See Creating closures in loops: A common mistake

and related questions:

  • JavaScript closure inside loops – simple practical example
  • Doesn't JavaScript support closures with local variables?
  • Access outside variable in loop from Javascript closure
  • How do JavaScript closures work?


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);
}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜