在js的懶漢式單例模式中寒屯,其實(shí)也用到了另一種設(shè)計(jì)模式遗契,即模塊模式。在傳統(tǒng)軟件工程中糠惫,模塊模式被定義為給類提供私有和公共封裝的一種方法疫剃,也就是我們常說的“模塊化”。在Java里面Class就是一種模塊硼讽,解決了屬性巢价、方法的封裝問題,它的模塊模式直接就融合到語言特性里面了固阁,因此也沒什么模塊模式的說法壤躲;然而對(duì)于JavaScript這種過于靈活的語言,這種最基本的私有化封裝卻需要用一個(gè)設(shè)計(jì)模式來解決了备燃。
在JavaScript中碉克,“private”是作為保留字,而不是關(guān)鍵字的并齐,也就是說漏麦,JavaScript沒有私有化這一功能(糾結(jié)吧)。解決解決這問題有兩種方法况褪,一是定義變量的時(shí)候在前面加上下劃線“_”撕贞,也就是告訴其他開發(fā)者,不要?jiǎng)舆@個(gè)變量喲测垛;另一種則是利用閉包捏膨。第一種方法并不是真正的私有,只是一種規(guī)范,如果要做到真正的私有号涯,還是要用第二種方法——閉包目胡。
我們創(chuàng)建一個(gè)匿名函數(shù),然后立即運(yùn)行它链快,此匿名函數(shù)中的所有代碼都存在于一個(gè)“閉包”之中誉己,從而得到私有性,并在特定作用域中保持可被訪問久又。
(function () {
//此作用域的所有變量巫延、函數(shù)依舊可在特定作用域中被訪問
})();
var Module = (function () {
var my={},
privateVar = 8;//私有屬性
function privateFun() {//私有方法
return ++privateVar;
};
my.publicVar = 1;//公共屬性
my.moduleFun = function () {//公共方法
return privateFun();
};
return my;
}());
console.log(Module.publicVar);//1
console.log(Module.publicFun());//9
在匿名函數(shù)中我們返回了一個(gè)my變量給Module作為外部訪問閉包內(nèi)容的接口,除閉包內(nèi)my之外的內(nèi)容都得到了私有性保護(hù)地消,閉包的數(shù)據(jù)在Module變量的作用域中保持可以訪問炉峰。
好了,模塊模式解決了JavaScript私有化的問題脉执,我們可以利用它來定義命名空間疼阔、單例、擁有私有化封裝的對(duì)象等等半夷。然而模塊模式也并非盡善盡美婆廊。例如,我們定義私有巫橄、公共變量的方法是不同的淘邻,當(dāng)開發(fā)過程中我們需要改變某個(gè)變量的可見性的時(shí)候,就不得不在它所有出現(xiàn)過的地方進(jìn)行修改湘换;并且JavaScript作為動(dòng)態(tài)編譯的語言宾舅,我們可以隨時(shí)給對(duì)象添加屬性、方法彩倚,然而我們在閉包之外定義的方法是無法直接訪問私有數(shù)據(jù)的