什么时候构建Javascript中的对象?

时间:2009-08-12 02:41:47

标签: javascript optimization object construction

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

5 个答案:

答案 0 :(得分:2)

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

那就是说,如果你真的想知道......试试看,然后找出答案。拨打不同版本1,000,000次,看看它有什么不同。

制作一个巨大版本的物体,看看是否有凹痕。观看任务管理器。试试不同的浏览器报告您的结果。这是一个更好的方式来找出,而不仅仅是在互联网上询问他们猜测可能是什么情况。

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

答案 1 :(得分: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; }
})();

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

答案 2 :(得分:1)

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

如果页面速度出现问题,我会测量页面中特定任务的时间。

如果创建对象非常昂贵(相对而言),那么我将转向情境#3。

添加'if'语句是没有意义的,如果它真的没有给你买任何东西......在这种情况下,创建一个简单/大的对象不会让你的CPU退缩。没有测量,你就没有优化 - 你只是盲目拍摄。

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

答案 3 :(得分:1)

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

其次,最后一个函数与第一个函数完全一样好。好吧,差不多。在第一个中,我认为你受垃圾收集器的支配,当你重新分配domElement.myDataProperty时,垃圾收集器会破坏旧对象。尽管如此,如果不确切知道垃圾收集器在目标平台上是如何工作的(并且它在浏览器中可能会有很大不同),那么您无法确定是否真的在保存任何工作。

答案 4 :(得分:1)

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