javascript 單例模式,javascript模式
單例模式是設計模式裡最基本也是最常用的模式之一,其特點是單體對象只存在一份執行個體,這樣你就能確保在你的所有代碼裡面都使用著同樣的全域資源。
在Java裡面實現單例模式的方法是首先將建構函式私人化,在內部建立一個私人的靜態變數儲存執行個體,然後通過一個靜態方法(一般取名為getInstance)將執行個體提供給外部存取。因為建構函式的私人化,所以外部無法對類進行執行個體化,而只能通過getInstance擷取,所以由始到終只有那一個靜態執行個體。
在Javascript裡面我們同樣可以借鑒這種思路。
(一)使用對象直接量
var Single = { name: "zhangsan", age: 20}
通過對象直接量建立的對象的確是一種最簡單的單例實現方式,這樣確實保證了全域裡只有一個Single對象,但是通過這種方式建立的對象“門戶大開”,並不能建立其私人成員(當然你可以將需要設定為私人成員的名字前加底線如_name來暗示它是私人的,但這並不是真實的私人化)。在上篇部落格裡我們討論了如何建立一個私人靜態成員,可以通過閉包實現。
使用閉包
var Single = (function(){ //私人成員 var age= 0; function priMethod(){ //... } return { //公有成員 name: "zhangsan", getAge: function(){ return age; }, setAge: function(_age){ age = _age; } }})();
在上面的例子裡面,我們通過立即執行函數得到了一個對象,這個對象依舊是唯一的,但它擁有了私人屬性和方法。
(二)通過new建立的對象
既然通過閉包可以私人化成員,那麼我們當然能模仿Java將對象私人靜態化,再通過getInstance方法傳遞出去,與java中的實現很相似。代碼如下:
var Single = (function(){ //唯一執行個體 var single = new function(){ //公有成員 this.name = "zhangsan"; this.say = function(){ console.log(this.name); } } return { getInstance: function(){ return single; } }})();var s1 = Single.getInstance();var s2 = Single.getInstance();console.log(s1 === s2); //true
其實對閉包熟悉了,上面的原理都是類似的,只是將執行個體作為了一個靜態私人成員。
惰性載入
不管是上面哪種方式,他們有一個共同的特點:單體對象在指令碼載入的時候就被建立出來了,對於非常大的對象來說開銷是很大的,那我們可以讓其執行個體化延遲到需要它的時候載入,這就稱之為惰性載入。
var Single = (function(){ //唯一執行個體 var single; //私人的建構函式 function Constructor(){ //公有成員 this.name = "zhangsan"; } return { getInstance: function(){ if(!single){ //如果single不存在,建立single single = new Constructor(); } return single; } }})();
在外部,我們通過getInstance方法進行訪問:
var s1 = Single.getInstance();var s2 = Single.getInstance();console.log(s1 === s2); //true
這樣,只有使用到執行個體的時候才會建立一個執行個體。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。