js實現面向切面的編程(AOP)

來源:互聯網
上載者:User

面向切面的編程(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") );
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.