javascript單例模式的理解

發表於2015-07-22

理解單例模式

單例模式的含義是: 保證一個類只有一個例項,並提供一個訪問它的全域性訪問點。實現的方法是:使用一個變數來標誌當前是否已經為某個類建立過物件,如果建立了,則在下一次獲取該類的例項時,直接返回之前建立的物件,否則就建立一個物件。這就確保了一個類只有一個例項物件。

比如如下程式碼是一個簡單的單例模式程式碼例項:

現在我們可以來使用下,初始化下,如下程式碼:

列印如下:

繼續如下測試:

如上程式碼測試,可以看到,先是例項化一次,傳aa給name引數,儲存到a變數中,第二次再次呼叫getIstance方法,由於例項已經存在,所以使用之前第一次建立過的物件,因此 a ===b 為true,a.getName()和b.getName()值列印都為aa;

我們還可以像如下方式來編寫程式碼:

使用代理實現單例模式

比如我現在想在頁面上建立一個div元素,如下使用代理實現單例模式的程式碼:

如上程式碼:我們把負責管理單例的邏輯移到了ProxySingletonCreateDiv 函式中,CreateDiv函式就是一個普通的函式,就是隻是負責建立div的方法,那麼具體的管理單例的邏輯交給ProxySingletonCreateDiv函式;

理解惰性單例

惰性單例的含義是:在需要的時候才建立物件例項,而前面我們講的是頁面載入完的時候就建立例項;比如我們在頁面上一個彈出視窗的div,還有許多其他的顯示元素,如果有些使用者不點選那個彈窗的話,那麼在頁面初始化的時候多建立了一些dom節點,如果我們使用惰性單例的話,我們就可以在使用者需要的時候才去建立dom節點;

我們首先來看看在頁面載入完成的時候去建立div彈窗。這個彈窗一開始是隱藏的,當使用者點選某個按鈕的時候,這個彈窗才顯示;程式碼如下:

<button id=”btn”>請點選我</button>

如上程式碼,我們點選按鈕的時候,才去建立div元素,但是每次點選的時候,我們都得建立元素,這樣也不合理的。但是如上程式碼,我們可以使用一個變數來判斷是否已經建立過div彈窗;如下所示:

編寫通用的惰性單例

如上程式碼雖然完成了惰性單例,但是有些問題;

  1. 違反了單一職責原則;比如建立物件和管理單例的邏輯都放在CreateDiv物件內部;
  2. 沒有把程式碼抽象出來,比如上面的是建立一個div元素,但是以後我想建立一個script元素或者一個iframe元素的話,那麼我們還需要複製上面的程式碼重寫下;

比如如果我現在按照上面建立div的方法,現在我們需要再建立一個iframe元素的話,程式碼需要改成如下:

我們現在肯定在考慮如何把上面的程式碼公用出來,這樣就可以實現抽象的程式碼,管理單例的邏輯程式碼其實可以抽象出來,這個邏輯是一樣的,使用一個變數來標誌是否建立過物件,如果是,在下次直接返回這個已經建立好的物件;

我們可以把這些邏輯封裝在getSingle函式內部,建立物件的方法fn被當成引數動態傳入getSingle函式;如下程式碼:

下面我們是使用getSingle建立一個div的方法如下:

比如現在我們需要建立一個iframe,那麼程式碼如下:

單例模式使用場景

有一些物件我們只需要一個的情況下,比如彈窗這樣的,全域性快取,遊覽器window物件等。

單例模式只會建立一個例項,且僅有一個例項,比如我們一剛開始講到的,

我們明明第一次傳的是aa,第二次傳的引數是bbb,為什麼都呼叫getName()方法後都列印出aa呢,這就是單例模式只建立一個例項的地方;

相關文章