JS

你了解什么是AOP吗?它的作用是什么?举个例子

发布于 2021-01-11 17:16:49
关注者
0
被浏览
164
3 个回答
  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    AOP是面向切面编程,相对于面向对象编程,面向对象是将需求分为了不同的类并有着自己独立的行为,而面向切面编程就是将通用需求从不同的类不同的行为中提取出来很多个类共享一个功能(比如实例中的输入数据检查),一旦发生变化,修改这个行为即可而不用修改很多个类。
    例子
    AOP方法

    // AOP工厂
    var aopFactory = function(before, after){
      // 构造方法,在原方法前后增加执行方法
      function constructor(originFun){
          function $_class(...data){
              var result;
              proxy.before(data);
              result = originFun.apply(this, data);
              proxy.after(data);
              return result;
          }
          return $_class;
      }
      var proxy = {
          // 添加被代理方法,参数a为被代理方法,参数b为目标对象
          add : function(a, b){
              var funName;
              // 判断参数a类型,可以为方法或方法名
              if(typeof a == "function"){
                  funName = a.name;
              }else if(typeof a == "string"){
                  funName = a;
              }else{
                  return;
              }
              // 不传对象时默认为window对象
              b = b || window;
              if(typeof b == "object" && b[funName]){
                  // 用$_class替换原方法
                  b[funName] = constructor(b[funName]);
              }
          },
          // 默认before为空方法
          before : function(){},
          // 默认after为空方法
          after : function(){}
      }
      // 注入特定的前后处理方法
      if(typeof before == "function"){
          proxy.before = before;
      }
      if(typeof after == "function"){
          proxy.after = after;
      }
      return proxy;
    }
    

    实例代码

    let checkProxy;
    // 验证参数是否为数字
    function checkNumber(...data){
        var i, length;
        for(i=0, length=data[0].length; i<length; i++){
            if(typeof data[0][i] != "number")
                console.log(data[0][i] + "不是数字");
        }
    }
    // 将checkNumber方法作为前置通知,生成验证参数是否为数字的构造器
    checkProxy = aopFactory(checkNumber);
    // 加法
    function Add(a,b){
        return a+b;
    }
    // 减法
    function Minus(a,b){
        return a-b;
    }
    
    // 为加减法生成验证参数是否为数字的代理方法
    checkProxy.add(Add);
    checkProxy.add(Minus);
    
  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。
    • 概念:AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, 再通过“动态织入”的方式掺入业务逻辑模块中。

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

    • demo

    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();
  • 面试哥
    面试哥 2021-01-12
    为面试而生,有面试问题,就找面试哥。

    装饰器版示例

    export function interceptor(type, fun) {
      return (target, name, descripter) => {
        const cacheValue = descripter.value;
        if (type === "before") {
          descripter.value = () => {
            fun();
            cacheValue();
          };
        } else if (type === "after") {
          descripter.value = () => {
            cacheValue();
            fun();
          };
        }
      };
    }
    @interceptor("after", dosomethingAfter.bind(this, [1, 2, 3]))
    @interceptor("before", dosomethingBefore)
    onSubmitOrder() {
      console.log("order submitted");
    }
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看