【问题标题】:When is an object in Javascript constructed?Javascript中的对象是什么时候构造的?
【发布时间】:2010-11-18 20:02:58
【问题描述】:

考虑以下 Javascript 函数 (1):

function setData(domElement) {
  domElement.myDataProperty = {
    'suppose': 'this',
    'object': 'is',
    'static': 'and',
    'pretty': 'big'
  };
};

现在我不喜欢这个函数的是每次调用函数时都会创建完全相同的对象。由于对象不会改变,我宁愿只创建一次。所以我们可以做如下调整(2):

var dataObject = {
  'suppose': 'this',
  'object': 'is',
  'static': 'and',
  'pretty': 'big'
};

function setData(domElement) {
  domElement.myDataProperty = dataObject;
};

现在该对象在脚本加载并存储在dataObject 时创建一次。但是让我们假设setData 只是偶尔被调用——在脚本加载的大多数时候,该函数并没有被使用。在这种情况下,我不喜欢这个函数的地方是对象总是被创建并保存在内存中,包括许多永远不会使用它的场合。我想你可以做这样的事情来达到理想的平衡(3):

var dataObject;

function setData(domElement) {
  if (!dataObject) {
    dataObject = {
      'suppose': 'this',
      'object': 'is',
      'static': 'and',
      'pretty': 'big'
    };
  }
  domElement.myDataProperty = dataObject;
};

这有意义吗?我认为这取决于解释器何时决定创建一个对象。是真的等到通过!dataObject条件,还是进入函数,尝试变聪明,决定提前构造?也许不同的 Javascript 引擎对此有不同的政策?

当然还有一个问题,即这些优化是否会在实践中发挥作用。显然,这取决于对象的大小、引擎的速度、可用资源的数量等因素。但总的来说,你会说哪一个是更重要的优化:从 (1) 到 (2)还是从(2)到(3)?

【问题讨论】:

    标签: javascript optimization object construction


    【解决方案1】:

    答案是,你不应该知道。您展示的示例之间几乎没有区别。您合理担心的唯一方法是,如果您有实际证据表明一种或另一种方式明显损害特定解释器的性能或内存使用。在此之前,为您担心这些事情是口译员的工作。

    也就是说,如果你真的想知道...试试看就知道了。调用不同的版本 1,000,000 次,看看有什么不同。

    制作一个巨大的物体版本,看看是否有凹痕。看任务管理器。尝试不同的浏览器。报告你的结果。这比仅仅在互联网上询问一群混蛋他们猜测的情况要好得多。

    请记住,无论如何,对象都必须在内存中,不管...作为 源文本

    【讨论】:

      【解决方案2】:

      必须创建一个新对象——不可能,部分原因是规范要求它,但主要是因为替代行为会违反直觉,采取:

      function f() {
          return {a : "b", c: "d"};
      }
      o=f();
      alert([o.c, o.e]); // Alerts "b,"
      delete o.c;
      o.e="f";
      o=f();
      alert([o.c, o.e]); // If the object was only created once this would produce ",f"
      

      您真的希望一个新的对象表达式不会实际生成您要求的对象吗?因为这就是你想要的。

      可以想象你只是想做:

      var myFunction = (function(){
          var object = {a: "b", c: "d"};
          return function() { return object; }
      })();
      

      这会得到你想要的效果,虽然你必须意识到你返回的对象是一个完全可变的可以改变的对象,每个人都将共享同一个变异实例。

      【讨论】:

      • 好点,但请记住,我在这里谈论的是永远不会改变的对象,例如典型的函数。
      • 没关系,JS说它可以改变,你不打算改变它的事实无关紧要。你会期待'return [1,2,3];'例如总是返回相同的对象?
      【解决方案3】:

      首先,我会在情况 #2 中实现它,并在页面加载后立即加载一次。

      如果页面速度有问题,我会测量页面内特定任务所花费的时间。

      如果创建对象的成本非常高(相对而言),那么我会转到情况 #3。

      如果它真的没有给你任何东西,那么添加'if'语句是没有意义的......在这种情况下,创建一个简单/大对象对你的CPU来说毫不费力。没有测量,你就没有优化——你只是盲目地射击。

      这实际上是我个人在 C++ 和 Java 中使用的一种相当常用的初始化方法。

      【讨论】:

        【解决方案4】:

        首先,这种优化在实践中并不重要。

        其次,最后一个函数和第一个函数一样好。嗯,差不多。首先,我假设您受垃圾收集器的支配,当您重新分配domElement.myDataProperty 时,它应该会破坏旧对象。尽管如此,如果不知道垃圾收集器在您的目标平台上是如何工作的(并且在不同的浏览器之间可能会有很大的不同),您无法确定自己是否真的节省了任何工作。

        【讨论】:

          【解决方案5】:

          在几个浏览器中尝试所有三个,看看哪个更快。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-10-17
            • 2023-03-05
            • 2013-06-17
            • 1970-01-01
            • 2017-11-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多