JavaScript是怎样AOP实现?

原创
2018/11/09 10:09
阅读数 1.9K

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

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

展开阅读全文
打赏
0
10 收藏
分享
加载中
vue 的 mixin 应该算个AOP
2018/11/12 17:17
回复
举报

引用来自“曾建凯”的评论

10年前就这么写了,早都麻木了,这年头应该用promise。

引用来自“KevinBlandy”的评论

aop应该是Proxy吧、、、Promise用异步身上的。
前端看 angular , 后端看 nest.js 。 AOP 实现更优雅
2018/11/10 16:37
回复
举报

引用来自“曾建凯”的评论

10年前就这么写了,早都麻木了,这年头应该用promise。

引用来自“KevinBlandy”的评论

aop应该是Proxy吧、、、Promise用异步身上的。
to young, aop 难倒没有异步?
2018/11/10 12:34
回复
举报

引用来自“银杏果果”的评论

动态语言几乎都能轻易的实现aop,特别是给对象动态添加属性和函数。
动态语言也正因为想怎么搞就怎么搞,所以在大项目上就会显得非常恶心
2018/11/09 17:26
回复
举报

引用来自“曾建凯”的评论

10年前就这么写了,早都麻木了,这年头应该用promise。
aop应该是Proxy吧、、、Promise用异步身上的。
2018/11/09 13:48
回复
举报
10年前就这么写了,早都麻木了,这年头应该用promise。
2018/11/09 13:06
回复
举报
动态语言几乎都能轻易的实现aop,特别是给对象动态添加属性和函数。
2018/11/09 12:12
回复
举报
更多评论
打赏
7 评论
10 收藏
0
分享
返回顶部
顶部