2009-08-12 26 views
3

考虑下面的JavaScript函数(1):何时构建Javascript中的对象?

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)?

回答

2

答案是,你不应该知道。你展示的例子在它们之间几乎没有什么区别。如果您有实际证据表明某种方式明显损害了特定口译员的表现或内存使用情况,那么您唯一可能担心的是唯一的方法。在此之前,解释者的工作就是为你担心这件事。

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

制作一个巨大版本的对象,看看是否有凹痕。观看任务管理器。尝试不同的浏览器。报告结果。这是一个更好的方法来找出问题,而不仅仅是在网上询问他们猜测可能是这样的一群人。

只是记住,对象必须是在内存中,无论如何,不​​管......作为原文

1

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

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

如果创建对象(相对来说)非常昂贵,那么我会转向情况#3。

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

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

1

首先,这种优化在实践中永远不会起作用。

其次,最后一个函数与第一个函数完全一样。好吧,差不多。在第一个,我想你是在垃圾收集器的摆布,当你重新分配domElement.myDataProperty时应该摧毁旧物体。不过,如果不清楚垃圾收集器在目标平台上的工作方式(并且它可能在不同的浏览器中有很大不同),那么您无法确定是否真的保存了任何工作。

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; } 
})(); 

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

+0

好点,但请记住,我正在谈论一个永远不会改变的对象,例如典型的功能。 – 2009-08-13 14:12:57

+0

并不重要,JS说它可以改变,你不打算改变它的事实是无关紧要的。你会期待'返回[1,2,3];'总是返回相同的对象,例如? – olliej 2009-08-13 22:19:44

1

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