1什么是單體
單體是javascript中最基本但是又是最有用的模式之一乳怎,它可以將代碼組織為一個邏輯單元,這個邏輯單元的代碼可以通過單一的變量進行訪問前弯。通過確保單體對象只存在一份實例,你就可以確信自己的所有代碼使用的同樣的全局資源,最簡單的單體實際就是一個對象字面量恕出。
var Signletion = {
attribute1: true,
attribute2: 10,
method1: function() {},
method2: function() {}
}
你可能沒有發(fā)覺這種單體對象與普通字面量有什么不同,按照傳統(tǒng)定義金蜀,單體是一個只能被實例化一次并且可以通過一個眾所周知的訪問點訪問的類。要是嚴格地的按照這個定義來說渊抄,前面的例子所展示的并不是一個單體,應(yīng)為它是一個不可被實例化的類班巩。這里我們把單體定義的更為廣義一些:單體是一個用來劃分命名空間并將一批方法和屬性組織在一起的對象嘶炭,如果它可以被實例化抱慌,那它只能被實例化一次眨猎。
2.1劃分命名空間
單體對象由兩個組成部分:包含著方法和屬性成員的對象自身,以及用于訪問它的變量寺渗。
在這里說下本人在項目中避免變量沖突的方法兰迫,一般在項目中定義變量都沒有用命名空間的習慣,都是在變量加自己名字的后綴汁果。
function findProduct(id){
....
}
//同項目 成員 的代碼
var resetProduct = $('reset-product');
var findProduct = $('find-product');
為了避免這種情況就需要命名空間。
var MyNameSpace ={
findProduct;function(){
}
}
var resetProduct = $('reset-product');
var findProduct = $('find-product');
命名空間還可以進一步分割鳄乏,現(xiàn)在的網(wǎng)頁的JavaScript中不僅有你自己的代碼棘利,還可能有庫代碼,廣告代碼等善玫。為了避免沖突,可以定義一個用來包含自己所有代碼的全局對象:
var GiantCorp = {}
然后把自己的全局變量裹唆,方法 分門別類的放入GiantCorp中只洒。
2.2用作特定網(wǎng)頁專用代碼的包裝器的單體
在項目中有些JavaScript是所有網(wǎng)頁都用的到的,但是有些JavaScript是某個網(wǎng)頁專用的毕谴,不會被用的別的地方距芬。最好把這兩種代碼分別包裝在自己的單體對象中循帐。
NameSpace.PageName = {
CONSTANT_1:true,
method1:function(){},
init:function(){
}
}
window.onload = function(){
NameSpace.PageName.init();
}
3擁有私有變量的單體
3.1使用下劃線
GiantCorp = {
//私有
_stripWhitespace:function(){},
//公共
stringToArray:function(){}
}
你可以通過下劃線告訴別人這是私有成員,不要修改它离斩,瘪匿,但是別人還是可以修改,棋弥,,人家不接受你的建議啊漾岳。粉寞。。
3.2使用閉包
MyNameSpace.Singletion = (function(){
var privateA = 1;
var privateMethod = function(){};
return {
publicA:true,
publicMethod:function(){}
}
})()
4惰性實例化
前面的單體都已一個共同點唧垦,他們都是在腳本加載時被創(chuàng)建出來的,對于資源密集或配置開銷較大的單體,也許更合適的方法是在使用的時候?qū)嵗?br>
這種惰性單體的特別之處在于蓄愁,對于他的訪問必須借助一個靜態(tài)方法:
Singleton.getInstance().methodName(),getInstance會檢查該單體是否已經(jīng)被實例化妇斤,如果么有那么將它實例化返回丹拯,如果已經(jīng)實例化直接返回現(xiàn)有實例站超。
MyNameSpace.Signleton = (function(){
var privateAttribute1 = false;
var privateAttribute2 = [1,2,3];
function privateMethod1(){}
function privateMethod2(){}
return {
publicAttribute1:true,
publicAttribute2:10,
publicMethod:function(){
}
}
})()
上面是一個正常的單體死相,下面我們把它改為惰性的:
MyNameSpace.Signleton = (function() {
var uniqueInstance;
function constructor() {
var privateAttribute1 = false;
var privateAttribute2 = [1, 2, 3];
function publicMethod1() {};
function publicMethod2() {};
return {
publicAttribute1: true,
publicAttribute2: 10,
publicMethod1: function() {},
publicMethod2: function() {},
}
}
return {
getInstance: function() {
if (!uniqueInstance) {
uniqueInstance = constructor();
}
return uniqueInstance;
}
}
})();
console.log(MyNameSpace.Signleton.getInstance().publicAttribute1);