JavaScript是怎样AOP实现?

作者: a333661d6d6e | 来源:发表于2018-11-09 22:12 被阅读12次

    AOP的概念,使用过Spring的人应该都不陌生了。Dojo中,也是支持AOP的。对于JavaScript的其他框架、库不知道有没有AOP的支持。而Aop又叫面向切面编程,用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被严重忽视的技术点,这次就来说说AOP在js中的妙用

    image.png

    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();
    

    结语

    感谢您的观看,如有不足之处,欢迎批评指正。

    相关文章

      网友评论

        本文标题:JavaScript是怎样AOP实现?

        本文链接:https://www.haomeiwen.com/subject/zgjwxqtx.html