你將了解一種設(shè)計(jì)模式-單體模式哨鸭!
你將了解單體模式的優(yōu)點(diǎn)!
單體模式
單體模式的思想在于保證一個特定類僅有一個實(shí)例蔓腐。這意味著當(dāng)您第二次使用同一個類創(chuàng)建新對象的時候望侈,應(yīng)該得到與第一次所創(chuàng)建對象完全相同對象。
如何將這種模式模式應(yīng)用到 JavaScript 傀蚌?在 JavaScript 中沒有類基显,只有對象。實(shí)際上當(dāng)創(chuàng)建一個新對象時善炫,此新對象已經(jīng)是單體了撩幽。
創(chuàng)建一個新對象(單體)例子 :
var person = {
name : 'Danile',
};
但在 JavaScript 中,對象之間永遠(yuǎn)不會完全相等销部,除非它們是同一個對象摸航,哪怕創(chuàng)建一個具有完全相同成員但同類對象,它也不會與第一個對象完全相同舅桩。例如:
var person2 = {
name : 'Danile',
};
person === person2 // false
person == person2 // false
so~~在 JavaScript 創(chuàng)建一個對象的時候酱虎,實(shí)際上就是創(chuàng)建一個單體。
使用 new 操作符
JavaScript 中具有 new 語法可使用構(gòu)造函數(shù)來創(chuàng)建對象擂涛,而且有時可能需要使用這種語法但單體實(shí)現(xiàn)读串。這種思想在于當(dāng)使用同一個構(gòu)造函數(shù)以 new 操作符來創(chuàng)建多個對象時,應(yīng)該僅獲得指向完全相同的對象的新指針撒妈。
var person1 = new person();
var person2 = new person();
person1 = person2; // true
person對象僅會在第一次調(diào)用構(gòu)造函數(shù)時被創(chuàng)建恢暖。在第二次(以及第三次以后)創(chuàng)建時將會返回同一個person對象。這就是為什么 person1 === person2狰右,因?yàn)樗鼈儽举|(zhì)上是指向同一個對象的兩個引用杰捂。
JavaScript 中如何實(shí)現(xiàn)該模式?
- 可以使用全局變量來存儲該實(shí)例棋蚌。(不推薦)
- 可以在構(gòu)造函數(shù)的靜態(tài)屬性中緩存該實(shí)例嫁佳。(缺點(diǎn)在于某些屬性是公開可訪問的屬性挨队,在外部代碼中可能會修改該屬性,以至于會丟失該實(shí)例)
- 可以將該實(shí)例包裝在閉包中蒿往。這樣可以保證該實(shí)例的私有性并且保證該實(shí)例不會被構(gòu)造函數(shù)以外的代碼所修改盛垦。(缺點(diǎn)是帶來了額外的閉包開銷)
閉包中的實(shí)例
直接上代碼:
function Universe() {
// 緩存實(shí)例
var instance = this;
// 緩存實(shí)例
this.start_time = 0;
this.bang = "Big";
//重寫該構(gòu)造函數(shù)
Universe = function () {
return instance ;
};
}
// 測試
var uni1 = new Universe();
var uni2 = new Universe();
uni1 === uni2; // true
由此可見,第一次調(diào)用原始構(gòu)造函數(shù)時瓤漏,它會像往常一樣返回 this腾夯。依次類推,再次調(diào)用時蔬充,將執(zhí)行重寫的構(gòu)造函數(shù)蝶俱。
單體模式的優(yōu)點(diǎn)
第一個優(yōu)點(diǎn):劃分命名空間
當(dāng)在做項(xiàng)目的時候,肯定不是一個人在做娃惯,而是一伙人跷乐,當(dāng)一個頁面中包含多個js文件的時候肥败,由于每個人的變量命名不同趾浅,很大程度上會發(fā)生變量覆蓋的情況,而用單體模式馒稍,把變量保存在對象中皿哨,很好的避免了這一點(diǎn)。
第二個優(yōu)點(diǎn):提高代碼的閱讀性纽谒,維護(hù)性
使用單體模式证膨,每個方法都被封裝在對象中,而且每個方法只做一件事鼓黔,所在在后期代碼維護(hù)上央勒,只需要維護(hù)特定位置的代碼就可以了。
第三個優(yōu)點(diǎn):可以實(shí)例化澳化,但只能實(shí)例化一次