Почему я не могу развернуть цикл в Javascript? - PullRequest
6 голосов
/ 24 июня 2009

Я работаю над веб-страницей, которая использует dojo и на которой есть число (6 в моем тестовом примере, но в общем случае переменная) виджетов проекта. Я вызываю dojo.addOnLoad (init), и в моей функции init () у меня есть следующие строки:

dojo.connect(dijit.byId("project" + 0).InputNode, "onChange",  function() {makeMatch(0);});
dojo.connect(dijit.byId("project" + 1).InputNode, "onChange",  function() {makeMatch(1);});
dojo.connect(dijit.byId("project" + 2).InputNode, "onChange",  function() {makeMatch(2);});
dojo.connect(dijit.byId("project" + 3).InputNode, "onChange",  function() {makeMatch(3);});
dojo.connect(dijit.byId("project" + 4).InputNode, "onChange",  function() {makeMatch(4);});
dojo.connect(dijit.byId("project" + 5).InputNode, "onChange",  function() {makeMatch(5);});

и изменения событий для виджетов моего проекта должным образом вызывают функцию makeMatch. Но если я заменю их циклом:

for (var i = 0; i < 6; i++) 
    dojo.connect(dijit.byId("project" + i).InputNode, "onChange",  function() {makeMatch(i);});

та же функция makeMatch (), тот же вызов init (), то же самое все остальное - просто сворачивание моих вызовов в цикл - функция makeMatch никогда не вызывается; объекты не подключены.

Что происходит, и как мне это исправить? Я пытался использовать dojo.query, но его поведение такое же, как для цикла for.

Ответы [ 2 ]

11 голосов
/ 24 июня 2009

это распространенная проблема при работе с замыканиями. попробуйте это:

for (var i = 0; i < 6; i++) {
    (function(i){
      dojo.connect(dijit.byId("project" + i).InputNode, "onChange",  function()   {makeMatch(i);});
    }(i));
}
8 голосов
/ 24 июня 2009

i - локальная переменная внутри цикла for. Когда вызывается функция onChange, все 6 функций имеют ссылку на i, которая равна 6.

Это та же проблема, что и # 4 на странице C # Brainteaser Джона Скита

List<Printer> printers = new List<Printer>();
for (int i=0; i < 10; i++)
{
    printers.Add(delegate { Console.WriteLine(i); });
}

foreach (Printer printer in printers)
{
    printer();
}

, который печатает все 10

...