經過拓展Function.prototype實現一個AOP

AOP(面向切面的編程)主要是將一些與核心業務邏輯模塊無關的功能抽離出來,這些功能一般包括日誌統計,安全控制,或者是異常處理等等。編程

咱們要作的就是拓展Function.prototype來「動態植入」到業務的邏輯模塊兒中,保持業務邏輯的純淨和高內聚。安全

如今咱們有一個函數app

var myFunc = function(){
    console.log(1);
}
myFunc();  //1

那咱們如何植入一個函數,讓他在這個函數執行以前執行呢?函數

如今咱們來拓展一個before函數。this

var myFunc = function(){
            console.log(1);
        }

        Function.prototype.before = function(fn){
            var _this = this;       //用來保存調用這個函數的引用,如myFunc調用此函數,則_this指向myFunc
            return function(){      //返回一個函數,至關於一個代理函數,也就是說,這裏包含了原函數和新函數,原函數指的是myFunc,新函數指的是fn
                fn.apply(this,arguments);   //修正this的指向,將this指針指向fn,將myFunc接收的參數傳給fn處理。
                return _this.apply(this,arguments);     //執行原函數
            }
        }

        myFunc = myFunc.before(function(){
            console.log(2);
        });

        myFunc([3,2,1]);   //先輸出2,再輸出1

此時,咱們會發如今執行myFunc這個函數以前,咱們會先執行before函數裏得代碼。prototype

如今咱們就能夠開森得用它來複用日誌統計等功能模塊。代理

固然,咱們也能夠把他看成一個過濾器來使用。指針

好比在傳入得時候,傳入得參數先用sort函數排序(注意:sort排序並不穩定):日誌

var myFunc = function(arr){
            console.log(1);
            console.log(arr);   //輸出 [1, 2, 2, 3, 4, 6, 7]
        }

        Function.prototype.before = function(fn){
            var _this = this;       //用來保存調用這個函數的引用,如myFunc調用此函數,則_this指向myFunc
            return function(){      //返回一個函數,至關於一個代理函數,也就是說,這裏包含了原函數和新函數,原函數指的是myFunc,新函數指的是fn
                fn.apply(this,arguments);   //修正this的指向,將this指針指向fn,將myFunc接收的參數傳給fn處理。
                return _this.apply(this,arguments);     //執行原函數
            }
        }

        myFunc = myFunc.before(function(arr){
            console.log(2);
            console.log(arr);   //輸出 [3, 2, 1, 6, 2, 7, 4]
            arr.sort();
        });

        myFunc([3,2,1,6,2,7,4]);   //先輸出2,再輸出1

寫出了一個before了,那麼after也簡單了:code

var myFunc = function(arr){
    console.log(1);
    console.log(arr);   //輸出 [1, 2, 2, 3, 4, 6, 7]
}

Function.prototype.before = function(fn){
    var _this = this;       //用來保存調用這個函數的引用,如myFunc調用此函數,則_this指向myFunc
    return function(){      //返回一個函數,至關於一個代理函數,也就是說,這裏包含了原函數和新函數,原函數指的是myFunc,新函數指的是fn
        fn.apply(this,arguments);   //修正this的指向,將this指針指向fn,將myFunc接收的參數傳給fn處理。
        return _this.apply(this,arguments);     //執行原函數
    }
}

Function.prototype.after = function(fn){
    var _this = this;
    return function(){
        var r = _this.apply(this,arguments); //先執行原函數,也就是myFunc
        fn.apply(this,arguments);   //再執行新函數
        return r;
    }
}
myFunc = myFunc.before(function(arr){
    console.log(2);
    console.log(arr);   //輸出 [3, 2, 1, 6, 2, 7, 4]
    arr.sort();
}).after(function(arr){
    console.log(3);
});

myFunc([3,2,1,6,2,7,4]);   //先輸出2,再輸出1,最後輸出3

好了,咱們在全局植入了這兩個函數以後,之後均可以開心的直接在別的函數後面.before().after()了。

相關文章
相關標籤/搜索