裝飾者模式:給對象動態(tài)添加職責的方式就是裝飾者模式,能夠在不改變原對象的情況下,在運行的時候給對象添加新的職責。
參考《javascript設計模式與開發(fā)實踐》
裝飾函數
如果在給一個函數或對象添加功能的時候不想動原函數,或者原函數是別的程序員寫的,這時候可以通過引用來增加函數功能
var a=function(){ //構造函數
alert(1);
};
var _a=a; //_a作為中間變量
a=function(){ //重新賦值a變量
_a(); //執(zhí)行a函數
alert(2); //添加的功能
}
下面重點是介紹一個AOP的例子,AOP是面向切面編程,在下面的函數運行的時候,可以給把函數看做有一個生命周期,分為 運行前(before),運行中,運行后(after)。在運行前,運行后可以給函數對象添加不同的職責,這些添加的職責不會影響原函數對象的運行。
在javascript中幾乎一切都是對象,函數作為一等對象,可以作為函數的參數傳遞,所以在js中使用裝飾者模式的時候后很大的便利性。
AOP的標準模型
//argument對象是函數調用時,隱式傳遞的函數參數
Function.prototype.before = function( beforefn ){
var __self = this; // 保存原函數的引用
return function(){ // 返回包含了原函數和新函數的"代理"函數
beforefn.apply( this, arguments ); // 執(zhí)行新函數,且保證this
// 不被劫持,新函數接受的參數也會被原封不動地傳入原函數,新函數在原函數之前執(zhí)行
return __self.apply( this, arguments ); // 執(zhí)行原函數并返
//回原函數的執(zhí)行結果, 并且保證this 不被劫持
}
}
Function.prototype.after = function( afterfn ){
var __self = this;
return function(){
var ret = __self.apply( this, arguments );
afterfn.apply( this, arguments );
return ret;
}
};
實例:點擊按鈕時彈框之后統(tǒng)計彈框的參數
//log函數作為參數傳遞
Function.prototype.after = function( afterfn ){
var __self = this; //保存原函數的引用,_在js中是可以使用的可以作為一個私有方法和變量的起始標志
return function(){ //返回函數復合體
var ret = __self.apply( this, arguments );//原函數調用
afterfn.apply( this, arguments );//after函數調用
return ret; //返回原函數
}
};
var showLogin = function(){
console.log( '打開登錄浮層' );
}
var log = function(){
console.log( '上報標簽為: ' + this.getAttribute( 'tag' ) );
}
showLogin = showLogin.after( log ); // 打開登錄浮層之后上報數據
document.getElementById( 'button' ).onclick = showLogin;
```
在javascript中。面向對象編程和函數式編程是不矛盾的。兩者結合起來威力更大。隨著學習的深入,你會覺得滿滿的都是套路和模式。到了這一步學習有點欲罷不能了。學習javascript真是有意思。