什么是單例模式?
定義:保證一個類只有一個實(shí)例指么,且提供一個可以訪問它的全局訪問點(diǎn)叔壤。
減少多次實(shí)例化造成的不必要資源和內(nèi)存的消耗。
function init (name) {
this.name = name
this.getName = function() {
return this.name
}
}
const Singleton = function () {
this.instance = null
}
Singleton.getInstance = function(name){
if (!this.instance) {
this.instance = new init(name)
}
return this.instance
}
const instanceA = Singleton.getInstance('Cindy')
const instanceB = Singleton.getInstance('Anna')
console.log(instanceA.getName()) // Cindy
console.log(instanceA === instanceB) // true
什么場景下使用單例模式
預(yù)期對象只有一個沈善,且能夠獲取到對象信息的時候乡数,例如全局緩存、瀏覽器中的window闻牡。
適用實(shí)例場景:
- 淘寶網(wǎng)點(diǎn)擊“登錄”按鈕净赴,會彈出登錄彈窗。無論點(diǎn)擊多少次這個按鈕罩润,這個彈窗實(shí)際上只需要創(chuàng)建一次就夠玖翅。
- 用戶編輯表單信息,在保存的如果檢驗(yàn)不通過會提示不同的error信息割以,顯然每次都重新創(chuàng)建一個彈窗的 DOM 是沒有必要的金度,這里就可以使用單例模式
在 JavaScript 中怎么實(shí)現(xiàn)單例模式
目前可以通過全局變量的方式來實(shí)現(xiàn),全局變量的方式創(chuàng)建的對象是唯一的严沥,并且在代碼任意位置都能被訪問到审姓。但是全局變量也存在十分明顯的缺點(diǎn):
- 全局污染
- 變量容易被覆蓋
一般情況下要盡量減少對全局變量的使用,如果一定要使用要盡量將污染降低到最小祝峻,方式有以下幾種:- 使用命名空間
適當(dāng)?shù)厥褂妹臻g魔吐,不能杜絕全局變量扎筒,只是減少全局變量的數(shù)量
- 使用命名空間
var nameSpace = {
name: 'a',
getName: function() {
return 'Name is:' + this.name
}
}
- 使用閉包封裝私有變量
把一些變量保存在閉包內(nèi)部,暴露一些對外的方法跟外界通信酬姆,這種方式可以完全規(guī)避對全局污染
(function() {
const __name = ''
const __age = 10
return {
getName() {
return 'Name is:' + __name
}
}
})()
什么是惰性單例模式
在需要的時候才實(shí)例化嗜桌,這是單例模式的重點(diǎn),在日常開發(fā)中十分實(shí)用,將上面的示例改造一下
function init (name) {
this.name = name
this.getName = function() {
return this.name
}
}
const Singleton = (function () {
let instance
return function(name) {
if(!instance) {
instance = new init(name)
}
return instance
}
})()
const instanceA = new Singleton('Cindy')
const instanceB = new Singleton('Anna')
console.log(instanceA.getName()) // Cindy
console.log(instanceA === instanceB) // true