let plane ={ fire:function(){ console.log('发射普通子弹') } } let missileDecorator = function () { console.log('发射导弹') } let atomDecorator = function(){ console.log('发射原子弹') } let fire1 = plane.fire plane.fire=function(){ fire1() missileDecorator() } let fire2 = plane.fire plane.fire = function(){ fire2() atomDecorator() } plane.fire()//发射普通子弹 发射导弹 射原子弹
AOP装饰函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Function.prototype.before = function(beforefn){ let _self = this//保存原函数的引用 returnfunction(){//返回包含了原函数和新函数的代理函数 beforefn.apply(this,arguments)//执行新函数,且保证this不被劫持,新函数接受的参数也会被原封不动地传入原函数,新函数在原函数之前执行 return _self.apply(this,arguments)//执行原函数并返回原函数的执行结果,并且保证this不被劫持 } } Function.prototype.after = function(afterfn){ let _self = this returnfunction(){ let ret = _self.apply(this,arguments) afterfn.apply(this,arguments) return ret } } document.getElementById= document.getElementById.before(function(){ alert(1) }) let button = document.getElementById('button')
应用:
数据统计上报:
把行为依照职责分成细粒度更细的函数,通过装饰把它们合并到一起,有助于编写一个松耦合高复用得到系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Function.prototype.after = function(afterfn){ let _self = this returnfunction(){ let ret = _self.apply(this,arguments) afterfn.apply(this,arguments) return ret } } let showLogin = function(){ console.log('打开登录浮层') } let log = function(){ console.log('上报标签为:'+this.getAttribute('tag')) } showLogin = showLogin.after(log)//打开浮层后上报数据 document.getElementById('button').onclick = showLogin