2009-08-12 25 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

在幾個瀏覽器中嘗試所有這三個,並找出哪個更快。