這次帶給大家JS實作單例模式的步奏詳解,JS實作單例模式的注意事項有哪些,下面就是實戰案例,一起來看一下。
傳統單例模式
# 保證一個類別僅有一個實例,並提供一個存取它的全域存取點。
實作單例核心思想
無非是用一個變數來標誌目前是否已經為某個類別創建過對象,如果是,則在下一次獲取該類別的實例時,直接返回之前創建的對象,接下來我們用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(),也只會回傳剛才創造的那個女朋友。至於新女朋友——不存在的。
單例常用場景
只需要產生一個唯一物件的時候,比如說頁面登入框,只可能有一個登入框,那麼你就可以用單例的思想去實現他,當然你不用單例的思想實現也行,那帶來的結果可能就是你每次要顯示登陸框的時候都要重新產生一個登陸框並顯示(耗費效能),或者是不小心顯示出了兩個登入框。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
localstorage和sessionstorage在Vue中怎麼使用
以上是JS實現單例模式的步奏詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!