JavaScript是怎樣AOP實現?

AOP的概念,使用過Spring的人應該都不陌生了。Dojo中,也是支持AOP的。對於JavaScript的其他框架、庫不知道有沒有AOP的支持。而Aop又叫面向切面編程,用過spring的同學肯定對它非常熟悉,而在js中,AOP是一個被嚴重忽視的技術點,這次就來說說AOP在js中的妙用

AOP的思維就是在目標方法前後加入代碼:

var result=null;

try{

before();

result = targetMethod(params);

}(catch e){

error();

}finlly{

    after();

}

return result;  

在JavaScript中要達到AOP的效果可以利用apply(ctx,arguments)來達到目的,請看下面demo:

這是一個原始的代碼:

function Person(options){  
                options = options ? options : {};  
                this.id = options.id;  
                this.age = options.age>0 ? options.age:0;  
            }  
            Person.prototype.show=function(){  
                console.log("id: "+this.id + " age: "+ this.age);  
            };  
            var p = new Person({  
                id:'test1',  
                age:1  
            });  
            p.show();  

現在想要對show方法植入代碼,利用apply這樣寫就Ojbk了:

var targetFunc = Person.prototype.show;  
            var proxyFunc  = function(){  
                var ctx = this;  
                console.log("before ...");  
                targetFunc.apply(ctx, arguments);  
                console.log("after ...");  
            }  
            Person.prototype.show = proxyFunc;  
            p = new Person({  
                id:"test2",  
                age:2//歡迎加入全棧開發交流圈一起學習交流:864305860  
            });//面向1-3年前端人員  
            p.show();//幫助突破技術瓶頸,提升思維能力  

如果要對各種方法植入,這樣寫肯定是不方便了,所以呢,將這個代碼織入的過程提成一個通用的工具:

function Interceptor(){  
            }  
            Interceptor.prototype.before = function(callContext, params){  
                console.log("before... ", callContext, params);  
            }  
            Interceptor.prototype.after = function(callContext, params){  
                console.log("after... ", callContext, params);  
            }  
            Interceptor.prototype.error = function(callContext, params){  
                console.log("error... ", callContext, params);  
            }  
              
            var InjectUtil = (function(){  
                function inject(obj, methodName, interceptor){  
                    var targetFun = obj\[methodName\];  
                    if(typeof targetFun == "function"){  
                        var proxyFun = genProxyFun(targetFun, interceptor);  
                        obj\[methodName\] = proxyFun;  
                    }  
                }  
                  
                function genProxyFun(targetFun, interceptor){  
                    var proxyFunc = function(){  
                        var ctx = this;  
                        var result = null;  
                        interceptor.before(ctx, arguments);  
                        try{//歡迎加入全棧開發交流圈一起學習交流:864305860  
                             result= targetFunc.apply(ctx, arguments);  
                        }catch(e){  
                            interceptor.error(ctx, arguments);  
                        }finally{  
                            interceptor.after(ctx, arguments);  
                        }  
                        return result;  
                    };  
                    return proxyFunc;  
                };  
                  
                return {  
                    inject:inject  
                }  
            })();  

測試:

Person.prototype.show=function(){  
                console.log("id: "+this.id + " age: "+ this.age);  
            };  
            InjectUtil.inject(Person.prototype,"show",new Interceptor());  
              
            var p = new Person({  
                id:"test3",  
                age:3  
            });  
            p.show();  

結語
> 感謝您的觀看,如有不足之處,歡迎批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章