装饰者模式:给对象动态添加职责的方式就是装饰者模式,能够在不改变原对象的情况下,在运行的时候给对象添加新的职责。
参考《javascript设计模式与开发实践》
装饰函数
如果在给一个函数或对象添加功能的时候不想动原函数,或者原函数是别的程序员写的,这时候可以通过引用来增加函数功能
var a=function(){ //构造函数
alert(1);
};
var _a=a; //_a作为中间变量
a=function(){ //重新赋值a变量
_a(); //执行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 ); // 执行新函数,且保证this
// 不被劫持,新函数接受的参数也会被原封不动地传入原函数,新函数在原函数之前执行
return __self.apply( this, arguments ); // 执行原函数并返
//回原函数的执行结果, 并且保证this 不被劫持
}
}
Function.prototype.after = function( afterfn ){
var __self = this;
return function(){
var ret = __self.apply( this, arguments );
afterfn.apply( this, arguments );
return ret;
}
};
实例:点击按钮时弹框之后统计弹框的参数
//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真是有意思。