這篇文章主要介紹了JavaScript實作單例模式實例以及程式碼講解,有需要的讀者們跟著學習參考下吧。
傳統單例模式
保證一個類別只有一個實例,並提供一個存取它的全域存取點。
實作單例核心思想
無非是用一個變數來標誌目前是否已經為某個類別建立過對象,如果是,則在下一次取得該類別的實例時,直接傳回之前建立的對象,接下來我們用JavaScript來強行實現這個思路,請看程式碼:
var Singleton = function( name ){ this.name = name; }; Singleton.prototype.getName = function(){ alert ( this.name ); }; Singleton.getInstance = (function(){ var instance = null; return function( name ){ if ( !instance ){ instance = new Singleton( name ); } return instance; } })();
我們透過Singleton.getInstance來取得Singleton類別的唯一對象,這樣確實是沒問題的,但是js本身是沒有類這種概念的,所以我們強行用傳統單例思想來實現是沒有任何意義的,這樣的程式碼又臭又長(其實是我自己看著不舒服嘻嘻嘻)。下面我們使用JavaScript的閉包來實作一個單例,請看程式碼:
var Createp = (function(){ var instance; var Createp = function( html ){ if ( instance ){ return instance; } this.html = html; this.init(); return instance = this; }; Createp.prototype.init = function(){ var p = document.createElement( 'p' ); p.innerHTML = this.html; document.body.appendChild( p ); }; return Createp; })(); var a = new Createp( 'sven1' ); var b = new Createp( 'sven2' ); alert ( a === b ); // true
可以看到,這樣我們確實用閉包來實作了一個單例,但這個程式碼還是高度耦合的,Createp的構造函數其實負責了兩件事情。第一是建立物件和執行初始化init方法,第二是保證只有一個物件。這樣的程式碼是職責不明確的,現在我們要把這兩個工作分開,構造函數就負責建構對象,至於判斷是返回現有對象還是構造新的對象並返回,我們交給另外一個函數去完成,其實也就是為了滿足一個程式設計思想:單一職責原則。這樣的程式碼才能更好的解耦,請看下面程式碼:
var Createp = function (html) { this.html = html; this.init(); }; Createp.prototype.init = function () { var p = document.createElement('p'); p.innerHTML = this.html; document.body.appendChild(p); }; var ProxySingletonCreatep = (function () { var instance; return function (html) { if (!instance) { instance = new Createp(html); } return instance; } })(); var a = new ProxySingletonCreatep('sven1'); var b = new ProxySingletonCreatep('sven2'); alert(a === b); //true
可以看到,現在我們的建構子Createp現在只負責建構對象,至於是返回現有物件還是建構新的物件並返回,這件事我們交給了代理類proxySingletonCreatep來處理,這樣的程式碼看著才舒(zhuang)服(bi)嘛!
最後貼一個高度抽象的單例模式程式碼,惰性單例的精髓!
//单例模式抽象,分离创建对象的函数和判断对象是否已经创建 var getSingle = function (fn) { var result; return function () { return result || ( result = fn.apply(this, arguments) ); } };
形參fn是我們的建構函數,我們只要傳入任何自己需要的建構函數,就能產生一個新的惰性單例。比如說傳入創建一個女朋友的建構函數,並且呼叫getSingle(),就能產生一個新的女朋友。如果以後再調getSingle(),也只會回傳剛才創造的那個女朋友。至於新女朋友——不存在的。
單例常用場景
只需要產生一個唯一物件的時候,比如說頁面登入框,只可能有一個登入框,那麼你就可以用單例的想法去實現他,當然你不用單例的思想實現也行,那帶來的結果可能就是你每次要顯示登陸框的時候都要重新生成一個登陸框並顯示(耗費性能),或者是不小心顯示出了兩個登入框。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
以上是在JavaScript中如何實作單例模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!