【问题标题】:Why shouldn't I make functions within a loop in Javascript? [duplicate]为什么我不应该在 Javascript 的循环中创建函数? [复制]
【发布时间】:2014-05-13 00:13:37
【问题描述】:

前几天我用 JSFiddle 检查了 my script 并在其中一行收到警告:Don't make functions within a loop


for (x = 0; x < 10; x++) {

    if (moment(now) > moment(then)) {

        doIt(x); // do it now

    } else {

        timeTillEnd = moment(then) - moment(now);

        setTimeout(function () {

            doIt(x); // do it later

        }, timeTillEnd); // <-- flagged here

    }
}

为什么我不应该在 Javascript 中的循环中创建函数?

另外:在此处显示的特定情况下使用函数会不会有问题?

【问题讨论】:

标签: javascript function loops


【解决方案1】:

您尝试做的可能是错误的,x 变量可能不是您所期望的。请参阅以下链接:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake

而且它们的创建成本也相对较高。

每个函数都带有它使用的变量的闭包,如果您正在执行“正常的命令式编程”并且只想通过为子任务定义内部函数来使代码看起来更清晰,那么这是不必要的开销:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Performance_considerations

在您的情况下,您似乎确实需要一个带有闭包的函数,因为您推迟了一些计算,但请确保您进行了正确的值捕获。

【讨论】:

  • 这不是(主要)原因。您是否有任何我可以阅读的声明来源?
  • 我仍然相信这不是 jslint 生成此警告的原因。我的意思是,应该清楚的是,一个函数使用的内存少于 1000 个函数。但同样适用于数组、对象、字符串、数字、任何类型的数据。
  • (好的,这个答案顶部的新原因对我来说更有意义。但是,IIFE 仍然会在循环中“创建函数”。)
  • 也许你对函数的内存占用感兴趣:groups.google.com/forum/#!topic/v8-users/BbvL5qFG_uc
  • 如果您可以参考一些技术文章引擎如何实现功能,我会很高兴。我同意它“感觉”创建函数可能比普通对象更昂贵,但 JS 引擎近年来也取得了许多进步,我只是不相信没有任何备份的这种说法。
【解决方案2】:

因为它可能导致意外的关闭行为(捕获的变量将具有在循环的最后一次迭代中分配的值)。您还将为每个循环获得一个新的函数实例,这会浪费资源。

现代浏览器为 setTimeout 使用第三个参数,它是函数的参数。见here。这也消除了闭包的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2018-10-11
    • 2011-07-13
    相关资源
    最近更新 更多