JavaScript实现AOP(面向切面编程)
什么是AOP?
AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, 再通过“动态织入”的方式掺入业务逻辑模块中。
AOP能给我们带来什么好处?
AOP的好处首先是可以保持业务逻辑模块的纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。
JavaScript实现AOP的思路?
通常,在 JavaScript 中实现 AOP,都是指把一个函数“动态织入”到另外一个函数之中,具体的实现技术有很多,下面我用扩展 Function.prototype 来做到这一点。请看下面代码:
Function.prototype.before = function (beforefn) {
var _self = this; //保存原函数引用
return function () { //返回包含了原函数和新函数的"代理函数"
beforefn.apply(this, arguments); //执行新函数,修正this
return _self.apply(this, arguments); //执行原函数
}
};
Function.prototype.after = function (afterfn) {
var _self = this;
return function () {
var ret = _self.apply(this, arguments);
afterfn.apply(this, arguments);
return ret;
}
};
var func = function () {
console.log("2")
}
func = func.before(function () {
console.log("1");
}).after(function () {
console.log("3");
} )
func();
执行结果如下:

我把负责打印数字1和打印数字3的两个函数通过AOP的方式动态植入func函数。通过执行上面的代码,我们看到控制台顺利地返回了执行结果1、2、3。
这种使用AOP的方式来给函数添加职责,也是JavaScript语言中的一种非常特别的巧妙的装饰者模式实现,下面我们来试试Function.prototype.before的威力,请看下面代码:
Function.prototype.before = function (beforefn) {
var __self = this; // 保存原函数的引用
return function () { // 返回包含了原函数和新函数的"代理"函数
beforefn.apply(this, arguments); // 执行新函数,且保证 this 不被劫持,新函数接受的参数 // 也会被原封不动地传入原函数,新函数在原函数之前执行
return __self.apply(this, arguments); // 执行原函数并返回原函数的执行结果, 2 // 并且保证 this 不被劫持
}
}
Function.prototype.after = function (afterfn) {
var __self = this;
return function () {
var ret = __self.apply(this, arguments);
afterfn.apply(this, arguments);
return ret;
}
};
document.getElementById = document.getElementById.before(function(){ alert (1);
});
var button = document.getElementById( 'button' );
执行结果:

我们给document.getElementById()做了一些装饰,以后我们每次调用这个方法之前都会先执行alert("1")这条语句,但是请注意我们这条语句并不是写在了document.getElementById()这个方法的源码中,而只是在他的外部给他加了装饰,这样带来好处就是我们可以在不改变原方法的源码的情况下为他添加一些新的行为。国际惯例,举个栗子:
我的同事写了一个函数可以输出当前时间,而我现在的需求是输出当前天气之后再输出当前时间,下面有两种解决思路:
(1)传统解决办法: 拿同事的函数过来,找到他输出时间的代码,在这些代码之前加入输出当前天气的代码
(2)装饰者模式解决办法:拿同事的函数过来,不用看他的源码,直接给他的函数装饰一下,装饰的东西也就是输出当前天气的代码。
两种方法都解决了问题,但是他们的出发点是完全不同的:
(1)方法是改造原函数的内部,我们就需要去理解源代码,然后做修改。
(2)方法是给原函数添加了一层外套,我们根本不用管原本函数的内部实现。
现在又有了新的需求:在输出当前时间之前,先输出当前温度
(1)方法,我们在第一个需求已经把同事的代码改的面目全非了,现在又要重新理解函数内部,并加以修改(删除输出当前天气的代码,然后加入输出当前温度的代码)。
(2)方法,同事原本的函数是没有变的,我们现在给同事的函数换一件套(输出当前温度)就可以了。
JavaScript实现AOP(面向切面编程)的更多相关文章
- Javascript aop(面向切面编程)之around(环绕)
Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...
- javascript AOP(面向切面编程)
var func = function () { console.log("2") } Function.prototype.before = function (beforefn ...
- AOP 面向切面编程, Attribute在项目中的应用
一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...
- AOP面向切面编程的四种实现
一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...
- Method Swizzling和AOP(面向切面编程)实践
Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...
- [转] AOP面向切面编程
AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- C# AOP 面向切面编程之 调用拦截
有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做AOP(面向切面编程) 不过需要注意的是,AOP的效率很慢,在需要高效率场合慎用. 以下是C#的AOP方法: 首先建立一个控制 ...
- 【原创】Android AOP面向切面编程AspectJ
一.背景: 在项目开发中,对 App 客户端重构后,发现用于统计用户行为的友盟统计代码和用户行为日志记录代码分散在各业务模块中,比如在视频模块,要想实现对用户对监控点的实时预览和远程回放行为进行统计, ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- 论AOP面向切面编程思想
原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...
随机推荐
- Handshakes
Description Last week, n students participated in the annual programming contest of Marjar Universit ...
- 【Aladdin Unity3D Shader编程】之三 光照模型(二)
高光反射模型 Specular=直射光*pow(cosθ,高光的参数) θ:是反射光和视野方向的夹角 编写高光反射Shader Shader "AladdinShader/07 Specul ...
- 【Win 10 应用开发】UI Composition 札记(三):与 XAML 集成
除了 DirectX 游戏开发,我们一般很少单独使用 UI Composition ,因此,与 XAML 互动并集成是必然结果.这样能够把两者的优势混合使用,让UI布局能够更灵活. 说到与 XAML ...
- 浅谈Jquery中的bind(),live(),delegate(),on()绑定事件方式 [转载]
前言 因为项目中经常会有利用jquery操作dom元素的增删操作,所以会涉及到dom元素的绑定事件方式,简单的归纳一下bind,live,delegate,on的区别,以便以后查阅,也希望该文章日后能 ...
- PHPMailer 发送邮件(二)
发现PHPMailer又做了较大的更新,以前发送邮件的方法已不太适用,刚好要做一个实验,需要搭建个环境,这里使用Gmail进行测试,现记录下来. 传送地址Github: PHPMailer 基本要求的 ...
- PaaS 调研:GAE与 AWS(上)
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:韩伟 起因 PaaS作为"云"的概念,已经流行了很久.从使用的角度上看,似乎就是:写一个PHP,然后可以直接传到服务 ...
- Oracle-4 - :超级适合初学者的入门级笔记:plsql,基本语法,记录类型,循环,游标,异常处理,存储过程,存储函数,触发器
初学者可以从查询到现在的pl/sql的内容都可以在我这里的笔记中找到,希望能帮到大家,视频资源在 资源, 我自己的全套笔记在 笔记 在pl/sql中可以继续使用的sql关键字有:update del ...
- rem布局配合less的快速开发
最近在进行静态页面的制作,为了方便和快速的布局,自己整理了一套工具可以快速的进行工作,剩余的时间大家都懂的,话不多说,来看具体的东西吧! 1.ps 下载这个软件→cutterman 十分强大的切图功能 ...
- 【1】maven来管理我的SSM项目
新建个maven项目,第一步当然是配置好自己需要的jar包,maven使用pom.xml管理 并不是每一个都有用,但是都是常见jar,方便以后自己调用来查找 <project xmlns=&qu ...
- python基础-------模块与包(一)
模块与包 Python中的py文件我们拿来调用的为之模块:主要有内置模块(Python解释器自带),第三方模块(别的开发者开发的),自定义模块. 目前我们学习的是内置模块与第三方模块. 通过impor ...