My Little World

AOP(切面)编程/装饰者模式

定义

在不改变对象自身的基础上,在程序运行期间给对象动态的添加职责

主要思想

在每次要执行具体函数B时,先执行A,在每次执行完B之后都执行C,
以此类推,有必要的话,在C执行完再执行D,从而形成执行链

具体实现

先用一个temp函数包住AB,再用一个final函数包住temp和C,这样,在执行final函数时,会按顺序A-B-C执行

1.使用普通函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let before=(fn,beforeFn)=>{
return (...args)=>{
beforeFn(args)
return fn(args)
}
}
let after = (fn,afterFn)=>{
return (...args)=>{
let ret = fn(args)
afterFn(args)
return ret
}
}

let a = ()=>{console.log(2)}
a = before(a,()=>{console.log(1)})
a = after(a,()=>{console.log(3)})
a() //1,2,3

2.改造Function对象,可以实现链式添加职责

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Function.prototype.before = function(beforeFn){
return ()=>{
beforeFn(arguments);
return this(arguments);
}
}
Function.prototype.after = function(afterFn){
return ()=>{
let ret = this(arguments);
afterFn(arguments);
return ret;
}
}
var func = function (){
console.log(2);
return 15}
func = func.before(()=>{console.log(1)}).after(()=>{console.log(3)})
func() //1,2,3 返回15

应用

1.数据统计上报
将点击响应事件包含的上报动作隔离出来,以after的顺序,装饰到点击事件响应函数上

2.动态改变函数参数
组装ajax请求参数时,在请求函数前装饰before函数,进行不同参数参加处理

3.插件式表单验证
在submit函数前装饰before函数进行不同条件验证

区分代理模式

代理模式的意图是当直接访问本体不方便或者不符合需要时,为这个本体提供一个替代者,
本体定义了关键功能,而代理提供或拒绝对它的访问,或者在访问本体之前做一些额外的事情
通常只有一层代理-本体的引用

AOP的作用用于对对象加入行为,一开始不能确定对象的全部功能时,
经常会形成一条装饰链