当前位置: 首页 > news >正文

JavaScript是怎样AOP实现?

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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

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

转载于:https://my.oschina.net/u/4018697/blog/2873969

相关文章:

  • 常用公共DNS服务器地址
  • BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
  • TCP/IP中的四元组、五元组、七元组
  • Win8/Win10下程序经常无响应的解决办法
  • 使用zt-exec库定时清理linux休眠进程
  • 像素密度和分辨率
  • 链表的销毁与清空(转)
  • NChome如何创建单据跟主子表还有扩展开发要怎么弄?
  • 数据库 外存储器读写数据物理过程
  • android四大组件之Service 简单音乐播放器
  • 已安装pymysql 但Pycharm 中import pymysql出错的解决方案
  • 关于字符串的倒置
  • 实时计算Flink——独享模式——Batch功能介绍
  • jQuery页面加载初始化的3种方法
  • MetaMask/provider-engine-1
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【知识碎片】第三方登录弹窗效果
  • 345-反转字符串中的元音字母
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • create-react-app做的留言板
  • HTTP中的ETag在移动客户端的应用
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • js写一个简单的选项卡
  • leetcode388. Longest Absolute File Path
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • PermissionScope Swift4 兼容问题
  • Rancher-k8s加速安装文档
  • React-Native - 收藏集 - 掘金
  • Selenium实战教程系列(二)---元素定位
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 从伪并行的 Python 多线程说起
  • 构建二叉树进行数值数组的去重及优化
  • 京东美团研发面经
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前言-如何学习区块链
  • 区块链技术特点之去中心化特性
  • 驱动程序原理
  • 深度学习入门:10门免费线上课程推荐
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • #android不同版本废弃api,新api。
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $forceUpdate()函数
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (算法)Travel Information Center
  • (正则)提取页面里的img标签
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • .a文件和.so文件
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)