为什么我不能在Javascript中滚动循环?

时间:2009-06-24 17:06:26

标签: javascript loops dojo closures

我正在开发一个使用dojo的网页,并且有一个项目小部件的数字(在我的测试用例中为6,但一般是变量)。我正在调用dojo.addOnLoad(ini​​t),在我的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 个答案:

答案 0 :(得分:11)

这是处理闭包时的常见问题。试试这个:

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

答案 1 :(得分:8)

我是for循环中的局部变量。当调用onChange函数时,所有6个函数都引用i,即6。

这与#4 on Jon Skeet's C# Brainteaser's page

的问题相同
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个