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

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

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

4
Fabian Fritz 10 Авг 2010 в 14:58

3 ответа

Лучший ответ

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

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

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

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

6
Gumbo 10 Авг 2010 в 11:03
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, чтобы значение оставалось неизменным

2
meder omuraliev 10 Авг 2010 в 11:07

В вашем примере 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
Paul Butcher 10 Авг 2010 в 11:12