javascript函数式编程09-高阶函数(AOP切片编程)

360 阅读2分钟

这是我参与更文挑战的第14天,活动详情查看: 更文挑战

紧跟上一篇 ,这一篇主要了解高阶函数(递归函数)

AOP切片编程?
  • AOP , 个人理解就是“定义什么方法(目标对象(Target))在什么时间(before, after, around)在什么位置(目标的哪个方法或者属性)做什么事情(advise 增强)”

  • AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来

  • 这些跟逻辑无关的功能通常包括日志统计安全控制异常处理性能监控等。把这些功能抽离出来后,在通过"动态织入"的方式渗入业务逻辑模块中。

  • 这样做的好处是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便的复用日志统计等功能模块。

实现方式

  • 扩展Function.prototype来做到这一点。代码如下:
 Function.prototype.before = function (beforefn) {
    var _self = this; //保存原函数的引用
    return function () { //返回包含原函数和新函数的代理函数
        beforefn.apply(this, arguments); //执行新函数,修正this
        return _self.apply(this, arguments); // 执行原函数
    }
};
Function.prototype.after = function (afterfn) {
    var _self = this; //保存原函数的引用
    return function () { //返回包含原函数和新函数的代理函数
        var ret = _self.apply(this, arguments);
        afterfn.apply(this, arguments);
        return ret;
    }
};
var func = function(){
    console.log(2);
}
func = func.before(function(){
    console.log(1);
}).after(function(){
    console.log(3)
});
func();
  • 使用高阶函数

    • 将目标函数 和 切面函数 作为参数传入
    • 返回一个类似代理的函数对象
// 原函数
var takePhoto = function (...args) {
  console.log('拍照片' + args)
}
// 定义 aop 函数
var after = function (fn, afterfn) {
  return function () {
    let res = fn.apply(this, arguments)
    afterfn.apply(this, arguments)
    return res
  }
}
// 装饰函数
var addFilter = function (...args) {
  console.log('加滤镜: ' + args)
}
// 用装饰函数装饰原函数
takePhoto = after(takePhoto, addFilter)
takePhoto('huanghaili', 'huanghailiang')
  • 使用ES6 的 class
class Test {
  constructor(name) {
    this.name = name
  }
  takePhoto (...args) {
    
    console.log('拍照:' + this.name + ' args: ' + args)
  }
}
// after AOP
function after (target, action, fn) {
  let old = target.prototype[action]
  if (old) {
    target.prototype[action] = function (...args) {
      let self = this
      old.call(self, ...args)
      fn.bind(self)(...args)
    }
  }
}
// 用 AOP 函数修饰原函数
after(Test, 'takePhoto', function () {
  console.log('添加滤镜')
  console.log(this.name)
  console.log(...arguments)
})
after(Test, 'takePhoto', function () {
  console.log('添加滤镜')
  console.log(this.name)
  console.log(...arguments)
})

let t = new Test('huangbiao')
t.takePhoto('huanghaili', 'huanghailiang')
  • 以上所述是给大家介绍的详解JS的AOP切片编程数,希望对大家有所帮助