單例模式簡(jiǎn)述
概念:
單例模式思想在于保證一個(gè)特定類(lèi)僅有一個(gè)實(shí)例司抱,意味著當(dāng)你第二次使用同一個(gè)類(lèi)創(chuàng)建信對(duì)象時(shí)款侵,應(yīng)得到和第一次創(chuàng)建對(duì)象完全相同片择。
特點(diǎn):
- 可以來(lái)劃分命名空間却盘,從而清除全局變量所帶來(lái)的風(fēng)險(xiǎn)夸研。
- 可以把代碼組織的更為一體邦蜜,便于閱讀和維護(hù)。
- 可以被實(shí)例化亥至,且實(shí)例化一次悼沈。
單例模式的簡(jiǎn)單實(shí)現(xiàn)
var Singleton = function(name){
this.name = name;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 獲取實(shí)例對(duì)象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {
instance = new Singleton(name);
}
return instance;
}
})();
// 測(cè)試單例模式的實(shí)例
var a = getInstance("aa");
var b = getInstance("bb");
console.log(b.getName()); // "aa"
console.log(a === b); // true
如上代碼,實(shí)現(xiàn)一個(gè)單例模式姐扮,無(wú)非就是使用一個(gè)變量來(lái)標(biāo)識(shí)該類(lèi)是否被實(shí)例化絮供,如果未被實(shí)例化的話(huà),那么我們可以實(shí)例化一次茶敏,否則的話(huà)壤靶,直接返回已經(jīng)被實(shí)例化的對(duì)象。
單例模式的運(yùn)用
日常工作中睡榆,我們經(jīng)常需要實(shí)現(xiàn)一個(gè)遮罩層萍肆,來(lái)防止用戶(hù)中斷頁(yè)面操作袍榆。所謂的遮罩層,就是一個(gè)大小跟窗口一致的半透明div層塘揣。我們要求頁(yè)面最多只能存在一個(gè)遮罩層包雀,此時(shí)運(yùn)用單例模式就再合適不過(guò)了。
以下是代碼實(shí)現(xiàn)~~~
var createMask = (function(){
var div;
return function(){
if(!div) {
div = document.createElement("div");
div.innerHTML = "遮罩層";
div.style.display = 'none';
document.body.appendChild(div);
}
return div;
}
})();
document.querySelector("body").onclick = function(){
var win = createMask();
win.style.display = "block";
}
如上代碼亲铡,雖然可以實(shí)現(xiàn)需求才写,但是不通用。如果業(yè)務(wù)又需要我們實(shí)現(xiàn)單例模式創(chuàng)建彈窗效果奖蔓,勢(shì)必需要copy一份代碼赞草,所以我們需要對(duì)單例模式進(jìn)行封裝。
單例模式的封裝
var getInstance = function(fn) {
var result;
return function(){
return result || (result = fn.call(this,arguments));
}
};
如上代碼:我們使用一個(gè)參數(shù)fn傳遞進(jìn)去吆鹤,如果有result這個(gè)實(shí)例的話(huà)厨疙,直接返回,否則的話(huà)疑务,會(huì)去執(zhí)行fn函數(shù)沾凄,并將結(jié)果保存到result中。
現(xiàn)在知允,不管我們需要實(shí)例化多少個(gè)對(duì)象撒蟀,都使用getInstance來(lái)實(shí)現(xiàn)。
以下是代碼示例~~~
var createMask = function(){
var div = document.createElement("div");
div.innerHTML = "遮罩層";
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
// 創(chuàng)建iframe
var createIframe = function(){
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
return iframe;
};
// 獲取實(shí)例的封裝代碼
var getInstance = function(fn) {
var result;
return function(){
return result || (result = fn.call(this,arguments));
}
};
// 測(cè)試創(chuàng)建遮罩層
var createSingleMask = getInstance(createMask);
document.querySelector("body").onclick = function(){
var win = createSingleMask();
win.style.display = "block";
};
// 測(cè)試創(chuàng)建iframe
var createSingleIframe = getInstance(createIframe);
document.querySelector("body").onclick = function(){
var win = createSingleIframe();
win.src = "https://jiangxia.github.io/";
};
單例模式在我們平時(shí)的應(yīng)用中用的比較多的温鸽,相當(dāng)于把我們的代碼封裝在一個(gè)起來(lái)保屯,只是暴露一個(gè)入口,從而避免全部變量的污染涤垫。