面向切面编程
面向切面编程Aspect Oriented Programming(AOP),主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中的各部分之间低耦合性的隔离效果。
对程序做无侵入干扰 将来对某些功能进行热插拔 不会影响其他 例如埋点 或者测某些功能性能
// 原始方法 很恶心 每个函数里面去写
// 测函数执行时间
function test() {
let startTime = new Date().getTime()
<!--函数功能-->
console.log('do something')
return 'test'
let endTime = new Date().getTime()
console.log(endTime - startTime)
}
// step1:
Function.prototype.before = function(fn) {
let self = this
fn()
self.apply(this,arguments)
}
Function.prototype.after = function(fn) {
let self = this
self.apply(this,arguments)
fn()
}
test.before(function(){
console.log('before')
})
test.after(function(){
console.log('after')
})
问题: 函数执行了2次
test作为中转 暂时先不执行
before 和before的回调送到 after里面去
after 和 after的回调送到before去
// step2:
改进:
<!--顺序:挂在 self -> test 执行before的回调 执行self 执行after的回调 -->
<!--执行before 不会执行self 而是挂载不执行 -->
Function.prototype.before = function(fn) {
let self = this
return function() {
<!--this指向 ~~~~ windows-->
<!--self指向 function实例 test -->
fn.apply(this,arguments) // 为后期改写this
self.apply(self,arguments)
}
}
Function.prototype.after = function(fn) {
let self = this
return function() {
// after 先执行本身this 再执行回调
// 这里的self 其实是before执行后返回的函数 先执行这个 再执行回调
self.apply(self,arguments)
fn.apply(this,arguments)
}
}
test.before(function(){
console.log('before')
}).after(function(){
console.log('after')
})()
// step3:
改进:
// 1.加上更加复杂的验证 假如before 返回false 不再执行
// 2. 拿到函数本身的返回值
Function.prototype.before = function(fn) {
let self = this
return function() {
if (fn.apply(this,arguments) == false) {
return false
}
return self.apply(self,arguments)
}
}
Function.prototype.after = function(fn) {
let self = this
return function() {
var result = self.apply(self,arguments)
if (result == false) {
return false
}
fn.apply(this,arguments)
return result
}
}
test.before(function(){
console.log('before')
return false // 假如before回调返回false,则不再执行
}).after(function(){
console.log('after')
})()
const timeTaken = callback => {
console.time('timeTaken'); const r = callback();
console.timeEnd('timeTaken'); return r;
};