傳送門:
JavaScript設計模式詳解-單身狗的你來看看單例模式
單例模式
單例模式就是在建立一個新的執行個體時,會首先判斷先前是否存在該執行個體,不存在則建立一個新執行個體并傳回,否則傳回之前的執行個體。
使用閉包實作單例模式
為什麼使用閉包?
因為我們可以使用閉包來擷取到目前執行個體的狀态是已經建立還是尚未建立。
比如
let getInstance = (function() {
var instance = null;
return function() {
console.log(instance);
if(!instance) {
instance = 'created';
}
return instance;
}
})();
getInstance(); // null
getInstance(); // created
上面這個例子很好地解釋了使用閉包如何構造單例模式。
由于作用域鍊,在執行
getInstance
時首先會查找自己的作用域中是否存在
instance
,不存在則重新指派,存在則直接傳回。
惰性單例
什麼是惰性?就是在需要時才建立。那麼非惰性的概念就是不需要時也一直存在,通過其他方式顯示和隐藏它。
有 惰性非單例, 非惰性非單例,惰性單例。這裡主要說一下惰性單例模式。
let createDiv = (function() {
let div;
return function() {
if(!div) {
div = document.createElement('div');
div.innerText = 'I\'m div';
document.body.append(div);
}
return div;
}
})();
createDiv();
createDiv();
就是上面的例子修改了一下,看的到不論執行多少次,都隻建立一個div。
單例很好展現出來了,惰性則展現在其隻有調用
createDiv()
時才會建立一個新執行個體。
職責分離的單例模式
有很多單例模式,但是集合在一起時,如果每次都一個個去判斷是否存在執行個體是不是有些備援?
于是出現了職責分離的單例模式,大概概念如下

代理器:
let getSingle = function(fn) {
let result;
return function() {
console.log(result);
if(!result) {
result = fn.apply(this, arguments);
}
return result;
}
}
div構造器:
let createDiv = function() {
let div;
div = document.createElement('div');
div.innerText = 'text';
document.body.append(div);
return div;
}
Img構造器:
let createImg = function(src) {
let oImg = document.createElement('img')
document.body.appendChild(oImg)
return oImg
}
建立各自的單例模式:
let createSingleDiv = getSingle(createDiv);
let createSingleImg = getSingle(createImg);
構造單例:
let div = createSingleDiv();
let div1 = createSingleDiv();
let img = createSingleImg();
你會發現,
div
和
div1
是引用一樣的執行個體的。