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

Posted

技术标签:

【中文标题】为啥我不能在 Javascript 中滚动循环?【英文标题】: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 循环的情况相同。

【问题讨论】:

【参考方案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 个

【讨论】:

以上是关于为啥我不能在 Javascript 中滚动循环?的主要内容,如果未能解决你的问题,请参考以下文章

为啥外部for循环变量不能用于内部for循环

为啥我不能在“foreach”循环中取消设置变量?

为啥jQuery不能监听document.body的滚动事件呢?

如何使用追加停止 JavaScript for 循环

为啥我不能在 iOS 7.0 中的 UIScrollView 中滚动?

为啥 VStack 不能在带有滚动视图的 GeometryReader 中工作?