我正在开发一个使用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循环案例相同。
答案 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个