【问题标题】:Don't make functions within a loop [duplicate]不要在循环中创建函数[重复]
【发布时间】:2012-04-25 16:58:24
【问题描述】:

在这种情况下解决 jslint 错误的正确方法是什么?我正在向使用它的对象添加一个 getter 函数。如果不在循环内创建函数,我不知道该怎么做。

for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: function() { // TODO solve function in loop.
            return this.name_;
       }
   };
}

【问题讨论】:

  • 为什么不完全消除 jslint 错误? Here's如何。
  • 因为错误是有原因的。我不认为编写这样的代码非常好,其中许多完全相同的函数被无缘无故地创建。
  • 有时 jslint 不一定是正确编码风格的终极指南...
  • 是的(我想,我已经很多年没有使用过 jslint 了),但是在我的书中,任何没有真正原因地创建大量相同资源的代码都是糟糕的代码。唯一可行的情况是它会带来性能提升。在这种情况下,您可能会争辩说它使代码更具可读性,但我认为这是非常微不足道的。作为 javascript 开发人员,您需要了解 this 的工作原理。

标签: javascript jslint


【解决方案1】:

将函数移出循环:

function dummy() {
    return this.name_;
}
// Or: var dummy = function() {return this.name;};
for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: dummy
   };
}

...或者只是使用文件顶部的loopfunc option 忽略该消息:

/*jshint loopfunc:true */

【讨论】:

  • 啊,我不认为“this”指针还能以这种方式工作。它不是指向虚拟函数而不是 result[i] 处的对象吗?换句话说,name_ 是否仍然正确找到?
  • @0x80 this 指向函数的上下文,在本例中为 results[i]jsfiddle.net/W5vfw
  • 太棒了!感谢您清楚地解释这一点。这是我对 Javascript 从来没有信心的事情之一。
  • @AmolMKulkarni 当函数表达式放在循环中时,它会在每次迭代中构造。将函数表达式/声明移到循环外有一些性能优势:jsperf.com/closure-vs-name-function-in-a-loop/2
  • 当你想向函数传递一些参数时会发生什么?