为了能通用的在函数前后执行某些操作
假设当前有一个 test 函数,我们需要测试 test 函数执行时消耗的时间,那么最先想到的做法是:
但如果需要测试更多的函数,我们就需要编写更多的 start、end,为了能通用的在函数前后执行某些操作,我们尝试引用面向切面编程(AOP):
最后测试代码test被改为:
function endTime(){
end = new Date()
console.log('speed: '+ (end - start))
}
test.before(startTime).after(endTime)('c')</code></pre>
作者:rayman_v
链接:https://www.jianshu.com/p/915b7dd1d42a
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
严格模式下
Function.prototype.before = function(fn){
return (function(){
fn()
return this
}.bind(this))()
}
Function.prototype.after = function(fn){
return (function(){
var result = this
fn()
return result
}.bind(this))()
}
// 使用
func.before(fn).after(fn)(args)
</code></pre>
用AOP实现职责链
将after函数改写,使得第一个函数返回‘nextSuccessor’时,将请求继续传递给下一个函数。这里的字符串‘nextSuccessor’只是一种自定义的状态,为了更好表达前一步骤是否满足条件。
具体案例请移步《JavaScript设计模式与开发实践》一书中的职责链模式p.186
用AOP来实现职责链既简单又巧妙,但这种把函数叠在一起的方式,同时也叠加来函数的作用域,如果链条太长的话,也会对性能有较大的影响。
return ref;
}
}
var order = order500yuan.after( order200yuan ).afte( orderNormal )</code></pre>
Decorators
Decorators是一个典型的AOP应用。装饰器基本原理如下:
// 相当于
class A{}
A = decorator(A) || A</code></pre>
因此对章节一进行改造
@before(function(){start = new Date()})
class MyTestableClass {
constructor(fn){
fn()
}
after(fn){
fn();
return this
}
}
var start,end;
new MyTestableClass(function(){
// do something
}).after(function(){end = new Date})</code></pre>
参考
- [1]
- [2] 有点难懂
- [3] [JavaScript设计模式与开发实践 p.186]()