zoukankan      html  css  js  c++  java
  • js实现面向切面的编程(AOP)

    js实现面向切面的编程(AOP)

    面向切面的编程(AOP) 还是有点意思的,可以在不修改原有代码的情况下增加新功能。有一些js框架实现AOP功能,但是有些时候我们并不能依赖于框架写程序(框架可能很笨重), 我们需要自己实现一些适合我们的功能模块。下面是我自己实现的js AOP,实现了before和after功能,仅供抛砖。

    如下是aspect.js,是实现AOP的全过程。


    (function(window, undefined){
     function aspect(type){
      return function(target, methodName, advice){
       var exist = target[methodName],
        dispatcher;

       if( !exist || exist.target != target ){
        dispatcher = target[methodName] =  function(){
         // before methods
         var beforeArr = dispatcher.before;
         var args = arguments;
         for(var l = beforeArr.length ; l--; ){
          args = beforeArr[l].advice.apply(this, args) || args;
         }
         // target method
         var rs = dispatcher.method.apply(this, args);
         // after methods
         var afterArr = dispatcher.after;
         for(var i = 0, ii = afterArr.length; i < ii; i++){
          rs = afterArr[i].advice.call(this, rs, args) || rs;
         }
         // return object
         return rs;
        }

        dispatcher.before = [];
        dispatcher.after = [];

        if( exist ){
         dispatcher.method = exist;
        }
        dispatcher.target = target;
       }

       var aspectArr = (dispatcher || exist)[type];
       var obj = {
        advice : advice,
        _index : aspectArr.length,
        remove : function(){
         aspectArr.splice(this._index, 1);
        }
       };
       aspectArr.push(obj);

       return obj;
      };
     }

     window.aspect = {
      before : aspect("before"),
      after : aspect("after")
     };

     return window.aspect;

    })(window, undefined);
    以下是测试代码:

     var as = window.aspect;

     var obj = {
      url:"",
      get : function(key){
       return this["key"];
      },
      set : function(key, value){
       this["key"] = value;
      }
     };

     var h1 = as.before(obj, "set", function(key, value){
      // 返回一个数组可以修改参数
      value += " before-1 ";
      //console.log(value);
      return [key, value];
     });

     var h2 = as.before(obj, "set", function(key, value){
      // 没有返回值则参数不会变化
      value += " before-2 ";
      //console.log(value);
     });

     obj.set("url", "http://mojijs.com");
     console.log( obj.get("url") );

     var h3 = as.after(obj, "get", function(value){
      // 没有返回值不会修改原函数的返回值
      value += " after-1 ";
      //console.log(value);
     });

     var h4 = as.after(obj, "get", function(value){
      // 有返回值会修改原函数的返回值
      value += " after-2 ";
      //console.log(value);
      return value;
     });

     console.log( obj.get("url") );

     h1.remove(); // 删除切面方法
     h4.remove(); // 删除切面方法

     obj.set("url", "http://baidu.com");
     console.log( obj.get("url") );

  • 相关阅读:
    算法提高 12-1三角形
    poj3723_Conscription
    算法提高 8-1因式分解
    算法提高 道路和航路
    算法训练 安慰奶牛
    最短路问题(Bellman/Dijkstra/Floyd)
    最小生成树 prime+heap
    算法训练 最短路
    算法训练 最大的算式
    poj3255 Roadblocks
  • 原文地址:https://www.cnblogs.com/shsgl/p/3934395.html
Copyright © 2011-2022 走看看