2012-02-23 50 views
5

我正在使用Javascript模塊模式來嘗試和實現類似於C#枚舉的功能。我目前正在考慮實施該功能的兩種方式,但我不明白一種方式與另一種方式的所有優點或優點。Javascript模式模式內存佔用和性能

下面是實現1:

var MyApp = (function (app) { 

    // Private Variable 
    var enums = { 
     ActionStatus: { 
      New: 1, 
      Open: 2, 
      Closed: 3 
     } 
    }; 

    // Public Method 
    app.getEnum = function (path) { 
     var value = enums;    
     var properties = path.split('.'); 
     for (var i = 0, len = properties.length; i < len; ++i) { 
      value = value[properties[i]]; 
     } 
     return value; 
    }; 

    return app; 

})(MyApp || {}); 

// Example usage 
var status = MyApp.getEnum("ActionStatus.Open"); 

現在實現2:

var MyApp = (function (app) { 

    // Public Property 
    app.Enums = { 
     ActionStatus: { 
      New: 1, 
      Open: 2, 
      Closed: 3 
     } 
    }; 

    return app; 

})(MyApp || {}); 

// Example usage 
var status = MyApp.Enums.ActionStatus.Open; 

的主要區別是在使用 「私有」 變量VS 「公共」 屬性來存儲枚舉。我認爲實現1會慢一點,但我不確定是否將枚舉保留爲「私有」可以減少內存使用量。任何人都可以解釋兩者(如果有)在內存佔用和性能方面的差異嗎?任何其他建議/意見表示讚賞。

回答

4

...但我不知道,如果保持枚舉爲「私有」減少內存使用

相反,如果有的話:你還必須有枚舉對象,你必須有一個功能來訪問它。

就速度而言,我不會擔心。添加的函數調用不會有任何真正的區別(I looked into it,當擔心使用新的forEach等等,甚至IE6與其大規模慢JS引擎,它只是沒關係)。

在幾年,你可能能有兩全其美的:這是枚舉只讀的,這要歸功於ECMAScript5的Object.defineProperties功能:

var Enums = Object.defineProperties({}, { 
    ActionStatus: { 
     value: Object.defineProperties({}, { 
      New: {value: 1}, 
      Open: {value: 2}, 
      Closed: {value: 3} 
     }) 
    } 
}); 

// Usage 
var n = Enums.ActionStatus.New; // 1 

默認情況下,創建的屬性defineProperties只讀

事實上,如果您添加一個ES5「墊片」在本地還沒有的瀏覽器上創建Object.defineProperties,現在基本上可以實現這一點。 「shimmed」版本將創建讀寫屬性,因爲只有本機支持的版本才能真正創建只讀屬性,但您現在可以編寫代碼並知道它在現代瀏覽器上可以像現在這樣工作(大約一半所有網上衝浪者目前都有他們),同時仍然工作,只是不太健壯,不太現代。

當然,EMCAScript6可能會做更多的事情,但這仍然是未來的事情。

+0

感謝您抽出寶貴時間回答並獲取ES5信息。你知道在瀏覽器內存管理方面,實現1如何存儲其私有變量與實現2的公有屬性的存儲?我試圖描述內存消耗,但我只能發現實現2使MyApp的對象大小更大,而實現1沒有。但我知道實現1必須將引用存儲到某處的私有變量。 – 2012-02-23 18:18:42

+0

@steve_ut:它被存儲在一個叫做(深吸一口氣)調用你正在用來創建對象的匿名函數的執行上下文的*變量綁定對象*中。 *(whew)* :-)這是[ES5規格](http://es5.github.com)術語([規範鏈接](http://www.ecma-international.org/publications/standards/Ecma- 262.htm))。每次調用一個函數都會得到一個變量綁定對象,它包含函數的參數,局部變量以及一些其他屬性。此處使用舊術語說明* [閉包不復雜](http://goo.gl/OzIQY)*。 – 2012-02-23 18:28:21

+0

@steve_ut:實際上,爲了更加正確,它存儲在一般的內存池中,並且變量綁定對象有一個對它的引用。這也是查看MyApp對象的更正確方法;無論您使用何種工具來映射「MyApp」的大小,都會給您提供一些簡化的信息。 JavaScript全是關於內存池中的對象,並且相互引用。來自實現2的'MyApp'對象實際上不包含* app.Enums引用的對象,不僅僅是實現1。 – 2012-02-23 18:31:56