3

考虑以下 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)?

4

5 回答 5

2

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

就是说,如果您真的想知道...尝试并找出答案。调用不同的版本 1,000,000 次,看看它有什么不同。

制作一个巨大的物体版本,看看是否会产生凹痕。看任务管理器。尝试不同的浏览器。报告你的结果。这是一种比仅仅在互联网上询问一群混蛋他们猜测可能是什么情况更好的方法。

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

于 2009-08-12T03:31:40.797 回答
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; }
})();

这将获得您想要的效果,尽管您必须意识到您返回的对象是一个完全可变的对象,可以更改,并且每个人都将共享同一个变异实例。

于 2009-08-12T06:39:15.957 回答
1

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

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

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

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

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

于 2009-08-12T03:05:54.373 回答
1

首先,这种优化在实践中永远不会重要。

其次,最后一个功能与第一个功能完全相同。嗯,差不多。首先,我想你受垃圾收集器的支配,当你重新分配时它应该销毁旧对象domElement.myDataProperty。尽管如此,如果不知道垃圾收集器在您的目标平台上是如何工作的(并且在不同的浏览器中可能会有很大的不同),您无法确定您是否真的保存了任何工作。

于 2009-08-12T03:11:02.883 回答
1

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

于 2009-08-12T15:47:57.720 回答