單例就是保證一個類只有一個實例,實現方法通常是先判斷實例存在與否,若是存在直接返回,若是不存在就建立了再返回,這就確保了一個類只有一個實例對象。在JavaScript裏,單例做爲一個命名空間提供者,從全局命名空間裏提供一個惟一的訪問點來訪問該對象。javascript
單例模式的思路是:一個類能返回一個對象的引用(而且永遠是同一個)和一個得到該實例的方法(靜態方法,一般使用 getInstance 名稱)。那麼當咱們調用這個方法時,若是類持有的引用不爲空就返回該引用,否者就建立該類的實例,而且將實例引用賦值給該類保持的那個引用再返回。同時將該類的構造函數定義爲私有方法,避免其餘函數使用該構造函數來實例化對象,只經過該類的靜態方法來獲得該類的惟一實例java
var singleton = { attr : 1, method : function(){ return this.attr; } } var t1 = singleton ; var t2 = singleton ;
那麼很顯然的, t1 === t2 。緩存
十分簡單,而且很是使用,不足之處在於沒有什麼封裝性,全部的屬性方法都是暴露的。對於一些須要使用私有變量的狀況就顯得愛莫能助了。固然在對於 this 的問題上也是有必定弊端的。安全
function Construct(){ // 確保只有單例 if( Construct.unique !== undefined ){ return Construct.unique; } // 其餘代碼 this.name = "NYF"; this.age="24"; Construct.unique = this; }
那麼也有的, t1 === t2 。閉包
也是很是簡單,無非就是提出一個屬性來作判斷,可是該方式也沒有安全性,一旦我在外部修改了Construct的unique屬性,那麼單例模式也就被破壞了。函數
對於大着 靈活 牌子的JS來講,任何問題都能找到 n 種答案,只不過讓我本身去掂量孰優孰劣而已,下面就簡單的舉幾個使用閉包實現單例模式的方法,無非也就是將建立了的單例緩存而已。this
var single = (function(){ var unique; function Construct(){ // ... 生成單例的構造函數的代碼 } unique = new Constuct(); return unique; })();
只要 每次講 var t1 = single; var t2 = single;便可。 與對象字面量方式相似。不過相對而言更安全一點,固然也不是絕對安全。spa
若是但願會用調用 single() 方式來使用,那麼也只須要將內部的 return 改成code
return function(){ return unique; }
以上方式也可使用 new 的方式來進行(形式主義的趕腳)。固然這邊只是給了閉包的一種例子而已,也能夠在 Construct 中判斷單例是否存在 等等。 各類方式在各個不一樣狀況作好選着便可。對象
總的來講,單例模式相對而言是各大模式中較爲簡單的,可是單例模式也是較爲經常使用而且頗有用的模式。在JS中尤其突出(每一個對象字面量均可以看作是一個單例麼~)。
記住,是否嚴格的只須要一個實例對象的類(雖然JS沒有類的概念),那麼就要考慮使用單例模式。
使用數據緩存來存儲該單例,用做判斷單例是否已經生成,是單例模式主要的實現思路。