天天看點

javascript常見程式設計模式舉例

        近期買到手了一本《javascript架構設計》,具體介紹開發js架構所用到的知識。初讀一點,樂帝脆弱的理論修養就暴露無遺了,是以專門加強理論修養,重看javascript程式設計模式的舉例。以下來介紹下js中,常見的程式設計模式。

   1.命名空間

   同其它進階語言一樣,js中的命名空間概念,也是為了降低命名沖突,但js沒有命名空間keyword。js實作命名空間的思路是定義一個全局變量,将此命名空間的變量和方法,定義為這個全局變量的屬性。

var MYAPP=MYAPP||{};//全局變量
MYAPP.dom={};//全局變量下的對象
	MYAPP.dom.Element=function(type,prop){
		var tmp=document.createElement(type);
		for(var i in prop)
		{
			tmp.setAttribute(i,prop[i]);
		}
		return tmp;
	}
	MYAPP.dom.Text=function(txt){
		return document.createTextNode(txt);
	}//兩個全局變量下對象的方法,這樣寫降低了全局變量的使用,降低了命名沖突,達到了命名空間的效果
	var e11=new MYAPP.dom.Element("a",{href:"www.baidu.com"});
	var e12=new MYAPP.dom.Text('click me');
	e11.appendChild(e12);
	document.body.appendChild(e11);      

    namespace函數,用于定義命名空間。

var MYAPP={};
	MYAPP.namespace=function(name){
		var parts=name.split('.');
		current=MYAPP;
		for(var i in parts)
		{
			if(!current[parts[i]])
			{
			current[parts[i]]={};//依次對屬性設定成對象
			}
			curent=current[parts[i]];//并将每一個對象都添為鍊式的前一個對象的屬性
		}
		return current;
	}
MYAPP.namespace('dom.style')      

    2.初始化分支和延遲定義模式

    這兩個模式不同之處,能夠從js架構設計角度考慮。構造一個架構,有些子產品必須初始化的,比方jquery的$符号,另外一些僅僅有被調用到才須要初始化操作。這種優點在于,保證了架構的可用性和載入效率上的最優化。

    初始化模式:

/初始化分支
	
var MYAPP={};
	MYAPP.event={
		addListener:null,
		removeListener:null
	};
	if(typeof window.addEventListener==='function'){
		MYAPP.event.addListener=function(e1,type,fn){
		e1.addEventListener(type,fn,false);
		};
		MYAPP.event.removeListener=function(e1,type,fn){
		e1.removeEventListener(type,fn,false);
		};
	}else if(typeof document.attachEvent==='function'){
		MYAPP.event.addListener=function(e1,type,fn){
		e1.attachEvent('on'+type,fn);
		};
		MYAPP.event.removeListener=function(e1,type,fn){
		e1.deleteEvent('on'+type,fn);
		};
	}else{
		MYAPP.event.addListener=function(e1,type,fn){
		e1['on'+type]=fn;
		};
		MYAPP.event.removeListener=function(e1,type,fn){
		e1['on'+type]=null;
		};
	}//載入腳本時運作分支,在子產品初始化過程中就将部分代碼進行處理,有利于提高效率      

   延遲定義模式:

//延遲定義 相對于初始化分支,延遲定義模式中,某些函數可能永遠不會被調用
//延遲模式會使初始化過程更輕量
var MYAPP={};
MYAPP.event={
		addListener:function(e1,type,fn){
	if(typeof e1.addEventListener==='function'){
		MYAPP.event.addListener=function(e1,type,fn){
		e1.addEventListener(type,fn,false);
		};
		
	}else if(typeof e1.attachEvent==='function'){
		MYAPP.event.addListener=function(e1,type,fn){
		e1.attachEvent('on'+type,fn);
		};
		
	}else{
		MYAPP.event.addListener=function(e1,type,fn){
		e1['on'+type]=fn;
		};
		
	}
	MYAPP.event.addListener(e1,type,fn);
	}
	
};//延遲定義的意義在于,假設用到就會初始化事件,不用就不會執行多餘代碼      

    3.配置對象的模式

    配置對象的模式,用于處理函數中有非常多個參數和方法的問題。用對象來替代多個參數,即讓這些參數都成為對象某一屬性。優勢在于:不用考慮參數的順序、跳過某些參數設定、擴充性和可讀性更強。

//配置對象
var MYAPP={};
	MYAPP.dom={};
		MYAPP.dom.Button=function(text,conf){//用配置對象作為函數參數,有利于解決函數參數順序問題,而且能夠跳過一些參數
			var b=document.createElement('input');
			b.type=config.type||'submit';
			b.value=text;
			b.font=conf.font||'Verdana';
			return b;
		}

var config={
	font:'Arial,Verdana,sanf-serif',
	color:'white'
}//配置對象,可讀性好,擴充性好,可依據須要随時改動配置對象
document.body.appendChild(new MYAPP.dom.Button('puuush',config));      

     4.私有函數公有化與自運作函數模式

    對象中私有函數對外不可見,私有函數公有化模式,用到了自運作函數的模式,傳回一個對象,保有對自由函數可訪問性。

//私有函數公有化與自運作函數
var MYAPP={};
	MYAPP.dom=(function(){
		var _setStyle=function(e1,prop,value){
			console.log('setSTyle');
		};
		var _getStyle=function(e1,prop){
			console.log('getStyle');
		};
		return{
			setStyle:_setStyle,
			getStyle:_getStyle,
			yetAnther:_setStyle
		};
	})();//通過傳回對象屬性保留對私有函數的訪問權限
	    //此種方法也是用自運作函數的方法使用方法        

    5.鍊式調用模式

//鍊式調用模式
	var obj=new MYAPP.dome.Element('span');
	obj.setText('hello,world').setStyle('color','red');
	//讓setText()方法傳回this就能夠實作鍊式調用了