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()了。