Open yizihan opened 6 years ago
AOP(Aspect Oriented Program):在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想。
创建before和after两个方法,分别可以在函数的前后无侵入的执行相关逻辑
// 功能函数 function test() { console.log(2); } function beforeFunc() { console.log(1) } function afterFunc() { console.log(3) } // 给函数原型添加before方法 (函数调用函数) // before => 先执行回调,再执行功能函数 Function.prototype.before = function (fn) { var _self = this; // this指向调用当前方法的函数 即test() fn(); // 首先,执行before方法传入的函数 _self.apply(this, arguments);// 然后,继续执行功能函数 // ==> test.apply(this, arguments); } // after => 先执行功能函数,再执行回调 Function.prototype.after = function (fn) { var _self = this; _self.apply(this, arguments); // 先执行调用当前方法的函数 fn(); // 再执行当前方法指定的函数 }; // test()被执行了两次 test.before(beforeFunc) // 1 2 test.after(afterFunc) // 2 3
存在的问题: 上述逻辑在同时调用before和after时,功能函数会发生重复调用。
before 回调和功能函数一起送到after after 功能函数和回调一起送到before
Function.prototype.before = function(fn) { console.log('aaa') var _self = this; // 因为before和after被添加到了原型链上 // 此时的匿名函数也有before和after方法 return function() { // 链式调用 将内容作为返回值推给后面的函数 console.log('ddd') // 执行beforeFunc函数 console.log(1) if (fn.apply(_self, arguments) === false) { return false; } console.log('eee') return _self.apply(_self, arguments) // 执行test函数 console.log(2) // 如果test函数有返回值,则将返回值return } }; Function.prototype.after = function(fn) { console.log('bbb') var _self = this; return function() { // 链式调用 将内容作为返回值推给后面的函数 console.log('ccc') // 将afterFunc函数缓存起来 // _self.apply(_self, arguments) 执行before中return的内容 var ret = _self.apply(_self, arguments); // 得到before函数return内容的return内容 即test函数的返回值 如果返回值为false,则停止运行当前函数 console.log('fff') if (ret === false) { return false; } console.log('ggg') fn.apply(_self, arguments); // 执行afterFunc函数 console.log(3) console.log('hhh') return ret; } }; test.before(beforeFunc).after(afterFunc)(); // aaa bbb ccc ddd 1 eee 2 fff ggg 3 hhh test.after(beforeFunc).before(afterFunc)(); // bbb aaa ddd 3 eee ccc 2 fff ggg 1 hhh
利用链式调用,将前面的 函数内容 作为后面函数体中的_self.apply(_self, arguments)调用,解决重复调用问题
_self.apply(_self, arguments)
注意闭包的this指向、执行作用域和执行栈
AOP
AOP(Aspect Oriented Program):在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想。
创建before和after两个方法,分别可以在函数的前后无侵入的执行相关逻辑
存在的问题: 上述逻辑在同时调用before和after时,功能函数会发生重复调用。
解决方案 - 链式调用
before 回调和功能函数一起送到after after 功能函数和回调一起送到before
利用链式调用,将前面的 函数内容 作为后面函数体中的
_self.apply(_self, arguments)
调用,解决重复调用问题