單體模式(singleton)
單體是在指令碼載入時建立的,能將一系列有關聯的變數和方法組織為一個邏輯單元,邏輯單元裡面的內容通過單一的變數進行訪問;
一個單體主要分為三部分
用於訪問內部資訊的入口變數(如:Sky)
屬性(如:nickName/age/timeInfo)
方法(如:sayHello)
基本結構
複製代碼 代碼如下:var Sky = {
/*
* 作用一,變數管理
*/
nickName: "sky",
age: "26",
/*
* 作用二,載入中初始設定變數
* 在載入過程中執行並初始化Sky.info
*/
timeInfo: function()
{
var _year = new Date().getFullYear();
return _year;
}(),
/*
* 作用三,函數管理,讓你的函數看起來不再那麼散亂
*/
sayHello: function()
{
alert("hello,world!");
}
}
//所有內部資訊通過Sky這個變數進行訪問;
alert(Sky.timeInfo);
以下是更詳細的說明,看完了這篇文章,相信你應該差不多瞭解了,網上好多高手的js寫法了,單體模式很常用。
單體是一個用來劃分命名空間並將一批相關的屬性和方法組織在一起的對象,如果他可以被執行個體化,那麼他只能被執行個體化一次。
單體模式是javascript裡面最基本但也是最有用的模式之一。
特點:
. 可以來劃分命名空間,從而清除全域變數所帶來的危險。
. 利用分支技術來來封裝瀏覽器之間的差異。
. 可以把程式碼群組織的更為一體,便於閱讀和維護。
單體的基本結構(正確寫法):
複製代碼 代碼如下:/*Basic Singleton*/
var Singleton = {
attribute1:true,
attribute2:10,
method1:function(){},
method2:function(){}
};
劃分命名空間:
複製代碼 代碼如下:var box = {
width:0,
height:0,
getArea:function(){
return this.width*this.height;//js中對象成的訪問必須是顯示的,即this是不能省略的
},
init:function(w,h){
// width = w;
// height = h;這種方式相當於定義了兩個全域變數,(沒加var聲明的變數為全域變數)
// 並不是對對象width和height的賦值
//下面是正確的
this.width = w;
this.height = h;
}
}//box劃分了一個命名空間,命名空間裡的變數只在空間裡有效
上面的單體中的所有的成員以及方法都是公有的(public),也就是在單體的外部可以對他們進行任意的改動,那為什麼說單體提供了一個命名空間呢?
我們繼續: 複製代碼 代碼如下:var box = {
width:0,
height:0,//單體的變數
getArea:function(){
return width*height;//中的,width,height其實並不是單體的變數,而是在init中定義的全域變數
}
init:function(w,h){
width = w;
height = h;
}
}//init中width,height其實並不是單體的變數
window.onload = function(){
var init = box.getArea();
alert(init);
}
由於沒有對init中的width,height進行初始化,所以會報錯,這樣改一下: 複製代碼 代碼如下:var box = {
width:0,
height:0,
getArea:function(){
return width*height;
},
init:function(w,h){
width = w;
height = h;
}
}
window.onload = function(){
width = 0;
height = 0;
//or box.init(0,0);
var init = box.getArea();
alert(init);
}
發現可以了,由於init和 getArea所用的width和height並不是歸單體所有的變數,而是一個全域變數,所以我們可以在單體外面進行隨意調用而不受影響
如果我們這樣寫一下就更明白了:
複製代碼 代碼如下:var box = {
width:0,
height:0,
getArea:function(){
return width*height;//js中對象成的訪問必須是顯示的,即this是不能省略的
},
init:function(w,h){
width = w;
height = h;
}
}//這裡的width,height其實並不是單體的對象
window.onload = function(){
width = 0;
height = 0;
var width = box.getArea();
alert(width);
}
這樣寫又會報錯了,可見我們以上的方式對於全域變數並沒有建立起一個命名空間,全域變數為我們帶來了危險。所以最上面的寫法是對的,我們來驗證一下: 複製代碼 代碼如下:var box = {
width:2,
height:2,
getArea:function(){
return this.width*this.height;//js中對象成的訪問必須是顯示的,即this是不能省略的
},
init:function(w,h){
this.width = w;
this.height = h;
}
}
window.onload = function(){
width = 0;
height = 0;
var width = box.getArea();
alert(width);
}
可見在window.onload中的width 和height已經沒有幹擾了,因為單體為單體中的width和height建立了一個命名空間。
成員的屬性:
討論完命名空間,我們來對單體變數和方法的屬性做一下設定。學過其他語言的人(java,c++,c#...)都應該很瞭解其中類成員的public和private,
雖然在javascript中沒有這麼嚴格的物件導向(oop),但是我們可以藉助閉包來進行一個模仿,畢竟有的變數設為public是很不好的。
複製代碼 代碼如下:var circle = (function(){
//pravite member!
var r = 5;
var pi = 3.1416;//後面用分號
return{//public member
getArea:function(){
return r*r*pi;//訪問私人成員不要加this
},//後面用逗號
//如果想改變r和pi的值,只能通過設定一個公有的函數來實現
init:function(setR){
r = setR;
}
}
})()
window.onload = function(){
circle.r = 0;//無法訪問私人成員,相當於又為circle建立了一個共有成員r
alert(circle.getArea());
circle.init(0);//通過公有的工具函數便可以訪問了。
alert(circle.getArea());
};
私人變數、方法是唯讀,公有變數、方法是可讀可寫的
訪問:
對於私人成員,直接存取即可,前面不用加任何修飾,
對於公有的訪問在單體範圍內前面要加上“this.”,在單體範圍外前面要加上“circle.”(單體名字.)
呵呵,似乎有點味道了!
.利用分支技術來來封裝瀏覽器之間的差異
注意的地方:
a一定要用閉包,實現即時綁定
b每個分支之間用分號隔開
c最後返回的是分支的名字
d調用的時候用單體名+分支的方法名; 複製代碼 代碼如下:// 利用單體的分支技術來定義XHR(XMLHttpRequest)對象,必須要用閉包才可以實現
var XHR = (function(){
//The three branches
var standard = {
cXHR:function(){
return new XMLHttpRequest();
}
};
var activeXNew = {
cXHR:function(){
return new ActiveXObject('Msxml2.XMLHttp');
}
};
var activeXOld = {
cXHR:function(){
return new ActiveXObject('Microsoft.XMLHttp');
}
};
//To assign(分配) the branch, try each method;return whatever doesn't fail
var testObject;
try{
testObject = standard.cXHR();
return standard;// return this branch if no error was thrown
}catch(e){
try{
testObject = activeXNew.cXHR();
return activeXNew;
}catch(e){
try{
testObject = activeXOld.cXHR();
return activeXOld;
}catch(e){
throw new Error('Create the XMLHttpRequestObject failed!');
}
}
}
})();
window.onload = function(){
alert(XHR.cXHR());
}
最後再囉嗦幾句:
對於單體據說是最常用的模式之一了,至於利弊嘛要在實踐中慢慢的體會了,由於本人也是初學,所以沒有太多的發言權,不足指出還忘高手指教