【问题标题】:Why can't I roll a loop in Javascript?为什么我不能在 Javascript 中滚动循环?
【发布时间】:2009-06-24 17:06:26
【问题描述】:

我正在开发一个使用 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 循环的情况相同。

【问题讨论】:

    标签: javascript loops dojo closures


    【解决方案1】:

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

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

    【讨论】:

    • 优秀;谢谢你;这完美地工作。我认为我需要很长时间才能理解闭包。
    • 获得一本名为“javascript the good parts”的书,您将了解闭包等内容。
    【解决方案2】:

    i 是 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 个

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-07
      • 2019-10-03
      • 2018-10-11
      • 2023-03-30
      • 1970-01-01
      • 2019-08-20
      • 1970-01-01
      • 2021-01-24
      相关资源
      最近更新 更多