[removed] Using the current for-loop counter-value

2019-01-15 10:44发布

问题:

on a website i want to do this: (simplified)

myHandlers = new Array();
for(var i = 0; i < 7; i++) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: function(bla) { /*...*/ alert(i); } // doesn't work,all return 7
  }
}

I could set the counter as another attribute of my Handler (which would copy the current value) and use it inside my function, but I guess, there is also a way to actually copy this value, no?

回答1:

When handlerFunc is called, the i inside the function refers to the i of the for loop. But that i does probably not have the same value any more.

Use a closure to bind the current value of i in the scope of an anonymous function:

handlerFunc: (function(i) { return function(bla) { /*...*/ alert(i); }; })(i)

Here an anonymous function (function(i) { … })(i) is used and called immediately. This function binds the value of i of the for loop to the local i. That i is then independent from the i of the for loop.



回答2:

var myHandlers = new Array();
for (var i = 0; i < 7; i++) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: 
    (function(i) { 
     return function(blah) { 
         alert(i) 
     }
     })(i)
  }))
}

Use a closure to bind the i so the value stays intact



回答3:

In your example, i in the functions is the same variable as i outside the functions. As i is incremented in the loop, so is it incremented within the functions. As a result, if the functions are called after the loop has finished, they will all alert "7".

You need to create a new variable with appropriate scope and copy the value of i into it.

Something like this would create the desired effect.

...
var pushHandler = function(i) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: function(bla) { /*...*/ alert(i); } // doesn't work,all return 7
  }
}
...
for(var i = 0; i < 7; i++) {
  pushHandler(i);
}

...