保證一個類僅有一個實例,並提供一個全局訪問點javascript
想象一下某些web應用,當點擊登陸按鈕時,會彈出一個登陸框,不管你點擊多少次這個登陸按鈕,登陸框都只會出現一個,不會出現多個登陸框。同時不會頻繁的進行刪除和添加,而是同一個登陸框進行隱藏和顯示,由於刪除和添加十分耗費性能,因此單例能夠達到最大化的效能利用。登陸框這個例子就是單例模式最典型的應用,符合業務的需求,又可以提升性能html
一個簡單的單例模式,無非就是用一個變量指示要建立的實例是否已經建立過了,若是已經建立過了,則在下一次使用實例時,直接返回複用,若是沒有建立過,則建立並保存到變量中。
java
可是這時候的這個單例類是「不透明」的,由於咱們一般習慣使用new XXX()
的方式來實例化一個類,而不是經過使用者不知道的XXX.getInstance()
的方式來獲取單例對象。
因此咱們應該使用透明的單例類web
先介紹下IIFEapp
IIFE( 當即調用函數表達式)是一個在定義時就會當即執行的 JavaScript 函數 --- MDN函數
eg.
之因此使用IIFE,就是限制JS的變量做用域,在ES5中,沒有塊級做用域,只有函數做用域一種,因此提供一種模擬塊級做用域的方法就是IIFE。咱們的透明單例模式就是使用IIFE來模擬。
性能
使用IIFE來避免變量污染,把在IIFE中建立的類return出去,供外部經過new XXX()
的形式調用。缺點是增長了程序的複雜度,不利於閱讀。
在構造函數CreateDiv中:this
實際上作了兩件事,prototype
這樣就不符合單一職責原則,這個構造函數就變得不純粹了。若是哪天我不想使用單例了,我要在頁面建立普通的實例,建立多個不同的div,還須要去修改CreateDiv構造函數,去掉控制單一實例的那一段,但頁面中使用此單例的代碼可能就用不了,故會帶來沒必要要的麻煩。因此咱們應該使用單例代理。代理
上面的問題咱們能夠用單例代理來解決,經過引入一個代理類,代理普通CreateDiv類,使之變爲單例類。
咱們把負責單例類管理的邏輯放到了單獨的ProxyCreateDiv類中,CreateDiv類仍是一個普通的建立實例的類,這樣保證了單一職責原則,組合起來就能達到單一職責原則。
以上就是單例類的建立模式,還有一類單例模式的應用,就是文章開頭說的登陸框,點擊登陸按鈕,登陸框會彈出,而不管點擊多少次,登陸框都只會彈出一個,這個登陸框就是單例的,稍後我會新寫一篇文章分享這種單例模式的應用,敬請關注。