装饰者模式
在不改变对象的基础上,在程序运行期间给对象动态地增加职责
比如天冷了就多穿件外套~
从结构上看更适合称为包装器(wrapper)模式。装饰者模式将一个对象嵌入另一个对象之中,实际上相当于这个对象被另一个对象包装起来,形成一条包装链。请求随着这条链依次传递到所有的对象,每个对象都有处理这条请求的机会
b要改变对象可以直接修改属性,而要改变函数在不碰原函数的前提下,就只能把它在另一个函数里引用,如下
var a = function(){
alert (1);
}
var _a = a;
a = function(){
_a();
alert (2);
}
a();
这样的写法有两个问题
- 每次需要改变函数都要多维护一个变量
- 原函数可能是一个对象的方法,但_a是window的属性,调用时会有this指向问题 接下来看下在职责链模式中提到的AOP,实现一个完美的装饰器
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;
}
};
唯一的不足是这个方法会污染原型,那我们可以换个方式,将原函数也作为参数
var before = function( fn, beforefn ){
return function(){
beforefn.apply( this, arguments );
return fn.apply( this, arguments );
}
}
var a = before(
function(){alert (3)},
function(){alert (2)}
);
a = before( a, function(){alert (1);} );
a();