1.單例模式解釋
單例就是保證一個類只有一個實體,實作的方法一般是先判斷實體存在與否,如果存在直接回傳,如果不存在就創建了再回傳,這就確保了一個類只有一個實體物件,在JavaScript里,單例作為一個命名空間提供者,從全域命名空間里提供一個唯一的訪問點來訪問該物件,
2.應用場景舉例
登錄頁
購物車
vuex
全域loading遮罩
......
3.代碼解釋
1.通過閉包和立即執行函式實作
var singletonPatten = (function() { // 單例建構式 function singleton(arg) { var arg = arg || {} this.x = arg.x || 1 this.y = arg.y || 1 } // 單例實體容器 var instance return function(arg) { if(!instance) { instance = new singleton(arg) } return instance
} }()) var singletonTest1 = singletonPatten({x: 2, y: 7}) var singletonTest2 = singletonPatten()
singleton1.z = 3 console.log(singletonTest1 === singletonTest2) //true console.log(singletonTest2.x) // 2
console.log(singletonTest2.z) // 3
第一次取實體時, 把singleton實體存到instance中,第二次實體已經存在直接回傳instance,所以第一次獲得的實體和第二次獲得的實體是相同的,
2.通過建構式實作
function Singleton(arg) { //實體是否已存在 if(typeof Singleton.instance === 'object') { return Singleton.instance } var arg = arg || {} this.x = arg.x || 1 this.y = arg.y || 1 //快取實體 Singleton.instance = this } var singleton1 = new Singleton({x: 2, y: 2}) var singleton2 = new Singleton() singleton1.z = 3 console.log(singleton1 === singleton2) //true console.log(singleton2.x) //2 console.log(singleton2.z) //3
獲得建構式實體前先判斷instance是否存在,存在則直接回傳,否則將建構式中的this進行快取,下次取實體可以直接回傳第一次獲得的實體
3.建構式重構實作
function Singleton(arg) { var arg = arg || {} //快取實體 var instance = this this.x = arg.x || 1 this.y = arg.y || 1 //重構建構式 Singleton = function() { return instance
}
} var singleton1 = new Singleton({x: 2, y: 2}) var singleton2 = new Singleton() singleton1.z = 3 console.log(singleton1 === singleton2) //true console.log(singleton2.x) //2 console.log(singleton2.z) //3
第一次獲得實體先將實體快取到instance中,然后就建構式進行一個重構,重構后的建構式直接回傳快取的實體instanceof,第二次獲得后便直接回傳直接快取的實體
4.通過class類實作
class Singleton { constructor(arg) { var arg = arg || {} this.x = arg.x || 1 this.y = arg.y || 1 } static getInstance(arg) { if(!Singleton.instance) { Singleton.instance = new Singleton(arg) }
return Singleton.instance
} } var singleton1 = Singleton.getInstance({x: 2, y: 2}) var singleton2 = Singleton.getInstance() singleton1.z = 3 console.log(singleton1 === singleton2) //true console.log(singleton2.x) //2 console.log(singleton2.z) //3
靜態方法getInstance獲取類的實體,先判斷instance上面是否快取實體,沒有快取,如果存在直接回傳,
4.實際應用場景
實作一個全域loading遮罩框
class Loading { constructor() { this.visile = false } show() { if(this.visile) { console.log('已經展示') return true } this.visile = true
} hide() { if(!this.visile) { console.log('已經隱藏') return true } this.visile = false } static getLoadingMask() { if(!Loading.instance) { Loading.instance = new Loading() } return Loading.instance } }
上述代碼,定義了一個loading遮罩的類,有兩個實體方法,show和hide,還有一個靜態類getInstanceMask
當兩處地方需要獲得loading遮罩實體進行操作
var loading1 = Loading.getLoadingMask() var loading2 = Loading.getLoadingMask() console.log(loading1 === loading2) //true loading1.show() loading1.hide() loading1.show() loading2.show() //已經展示 loading2.hide() loading2.hide() //已經隱藏
當對loading1和loading2執行show方法,第二次執行show會報已經展示,表示是同一個laoding遮罩實體
這樣就實作了一個單例模式的實際應用場景,
其他的如基于vue的vuex就是最典型的單例模式,因為它的全域狀態管理器,只能存在一個,不能多個,
單例模式實際為了節省資源而存在的一種模式,也是很常見的一種模式之一,
end !!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/199912.html
標籤:JavaScript
上一篇:VUE+element實戰運用
下一篇:VUE+element實戰運用
