JavaScript: использование текущего значения счетчика цикла внутри функции () {}? - PullRequest
4 голосов
/ 10 августа 2010

на сайте я хочу сделать это: (упрощенно)

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

Я мог бы установить счетчик как еще один атрибут моего обработчика (который будет копировать текущее значение) и использовать его внутри моей функции, но я думаю, есть также способ на самом деле скопировать это значение, не так ли?

Ответы [ 3 ]

6 голосов
/ 10 августа 2010

Когда вызывается handlerFunc , i внутри функции относится к i цикла for.Но это i, вероятно, больше не имеет того же значения.

Используйте замыкание для привязки текущего значения i в области действия анонимной функции:

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

Здесь анонимная функция (function(i) { … })(i) используется и вызывается немедленно.Эта функция связывает значение i цикла for с локальным i.Тогда i не зависит от i цикла for.

2 голосов
/ 10 августа 2010

В вашем примере i в функциях - это та же переменная, что и i вне функций. Как i увеличивается в цикле, так и увеличивается внутри функций. В результате, если функции вызываются после завершения цикла, все они будут предупреждать «7».

Вам необходимо создать новую переменную с соответствующей областью действия и скопировать в нее значение i.

Примерно так создаст желаемый эффект.

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

...
2 голосов
/ 10 августа 2010
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)
  }))
}

Используйте замыкание, чтобы связать i, чтобы значение не изменилось

...