2011-06-17 27 views
2

下面是js代碼的兩個樣品:的Javascript全局上下文的可變對象VS功能激活對象

A.功能_foo被全局上下文

function _foo(){ //some code here 
    } 

    //... some unrelated code here 

    var foo = function(){ 
    var result = _foo(); 
    return result; 
    } 

B.功能_foo定義內定義在功能範圍內

var foo = function(){ 
    function _foo(){ //some code here 
    } 

    var result = _foo(); 
    return result; 
}; 

其中之一是一個在內存管理方面的編程實踐?由於函數foo將在應用程序中多次調用,因此在應用程序的全局上下文中保留_foo並且不在函數上下文中每次調用foo時都更好?或者由於_foo將(大部分)在foo內部使用,因此將其保留爲激活對象的一部分是有意義的?

+1

這兩個例子有不同的語義。使用表達所需語義的「最清晰」版本。擔心表現時 - 或者說 - 如果 - 它成爲一個問題。 (哦,'_foo'在上面的「全局上下文」中永遠不會被定義 - *每個*函數作用域都會引入一個新的執行上下文。) – 2011-06-17 07:31:52

+0

正確的,「全局上下文」在這裏是一個誤稱,因爲'_foo'在一個匿名函數的範圍。我只是編輯了代碼以避免混淆。目的是區分我懷疑的案件。 – fenderplayer 2011-06-17 07:38:32

+0

[正在刪除本地函數的一個微優化](http://stackoverflow.com/questions/4747581/is-not-having-local-functions-a-micro-optimisation)。 @fenderplayer它也取決於你的瀏覽器範圍,對於你不關心的FF4和Chrome,你在乎IE6支持低劣的JScript引擎。 – Raynos 2011-06-17 07:50:47

回答

4

C:緩存

var foo = (function(){ 
    function _foo(){ //some code here 
    } 
    return function() { 
    var result = _foo(); 
    return result; 
    } 
}()); 

美孚立即執行,功能_foo只聲明一次。

在現代瀏覽器中,這比「全局」函數慢了5%。

相關Benchmark

+0

酷! C似乎比B好。 – fenderplayer 2011-06-17 20:19:49

0

嘗試在全局上下文中創建您的函數,並使用閉包函數作爲特定於原始功能請求的異步回調函數。由於匿名函數調用過多,您可能會陷入令人討厭的內存泄漏,因爲JavaScript會保留在閉包中使用的頂級變量。

如果您嘗試爲私人會員設計OO樣式,您可能還想使用閉包函數。在'面向對象的javascript'上做一些Google/Stackoverflow搜索,並且獲得關於該特定主題的更多設計幫助。

引自MDN:

https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope

閉包可以佔用大量的內存。只有當返回的內部不再可訪問時,內存才能被釋放... 由於效率低下,應儘可能避免關閉,即儘可能避免嵌套功能。

同樣,考慮到OO設計是很好的......將你的函數包裝到一個對象中,這樣你可以靜態地調用它們或通過一個對象引用也是一個好的設計。

+0

不要在全局範圍內創建函數。這很醜陋。內存泄漏也來自壞的引擎和對DOM的循環引用。 – Raynos 2011-06-17 07:57:31

+0

取決於瀏覽器,但是您對DOM引用是正確的。在某些情況下,AJAX調用會受到閉包引用的影響,因爲我自己也遇到了這個令人討厭的錯誤。功能在全球範圍內,醜陋?這絕對是主觀的。 – ricosrealm 2011-06-17 08:20:44

+0

我是儘量減少範圍污染。它所處的範圍鏈越遠,查找時間就越長。 – Raynos 2011-06-17 08:23:46

1

要直接回答你的問題,如果你每次需要實例化一個foo對象,那麼在全局範圍聲明它將是一個更快的選擇。

但是,在JavaScript中,從性能角度來看,幾乎肯定會有更快的獲勝,這通常與DOM交互有關。

在這些例子中,我會建議你堅持最好的編程習慣。如果這是C#,Java或其他更強類型的語言,你會怎麼做?那麼,你將無法要聲明一個全局函數,所以你會把它放進一類,無論是作爲一個靜態方法,或者作爲一個公共方法:

var foo = function(){}; 

//static method 
foo._foo = function(){ 
    alert("_foo"); 
}; 

//public method 
foo.prototype._foo2 = function(){ 
    alert("_foo2"); 
}; 

//calling static method 
foo._foo(); 

//instantiating and calling public method: 
var f = new foo(); 
f._foo2(); 

//note: this won't work (as we would expect!) 
foo._foo2(); 

這樣的大多數東西都是與貿易偏好,偏愛這裏的風格和結構而非性能。

+0

我同意,並且這樣更容易調試 – fenderplayer 2011-06-17 22:01:06