【问题标题】:Will an array inside of a JavaScript function be recreated on every call?每次调用都会重新创建 JavaScript 函数内部的数组吗?
【发布时间】:2016-07-07 03:57:47
【问题描述】:

假设我有一个函数dayToString,定义如下:

function dayToString(n) {
  return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][n];
}

很简单。用法可能如下所示:

var d = new Date();

var todayAsString = dayToString(d.getDay());

我的问题是,dayToString 中的数组是在每次调用时重新创建的,还是只创建一次?

编辑

澄清:我知道如何通过闭包或外部数组手动避免这种重新分配。澄清一下我的初衷:当前的 JavaScript 引擎(V8、SpiderMonkey、JavaScriptCore、Chakra 等)是否足够聪明,可以意识到数组是静态的,并且是这样处理的? JS 规范中是否有某些内容阻止了这种优化?

【问题讨论】:

    标签: javascript function v8 spidermonkey javascriptcore


    【解决方案1】:

    这取决于运行时编译器。所以这个问题不能用是或否来回答。

    但我说,不,因为在编译器看来,函数只有一个实例,而且函数的内容是静态的。

    【讨论】:

    • 这是我在提出问题时考虑的那种优化。我对 V8、JSC 等来源不够熟悉,无法确定这种优化是否在任何合理的时间内完成,但如果你有任何证据支持你的主张,那就是我所追求的。
    【解决方案2】:

    是的,每次都会重新创建数组。

    只创建一次数组:

    1) 在函数上模拟static property

    dayToString.weekDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    function dayToString(n) {
      return dayToString.weekDays[n];
    }
    

    2) 或者创建一个closure to keep the week days 隔离:

    var dayToString = (function(n) {
      var weekDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
      return function(n) {
        return weekDays[n];
      }
    })();
    

    【讨论】:

    • 你的 2 中的一个好技巧,我经常使用它来泛化为一个接受数组并返回闭包的函数,但我的问题更多是关于如何“聪明”的问题JS引擎是。他们是否意识到数组本身是静态的并将其视为静态数组?
    • @HoagyCarmichael 这取决于实现,引擎可以优化这部分的可能性很大。但我不会在编码阶段将此作为参数,因为 JavaScript 规范规定每次调用函数时都会重新创建范围。
    【解决方案3】:

    是的,您正在定义它并在每次调用时返回它。为避免这种情况,请在函数外部定义:

    var arrayOfDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    function dayToString(n) {
      return arrayOfDays[n];
    }
    

    【讨论】:

    • 我知道这种方法可以避免我们假设的重新分配,但我的意思是这个问题更适合 V8、JSC,朋友们可以在函数中看到这个静态项并这样对待它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多