通过拓展Function.prototype实现一个AOP
AOP(面向切面的编程)主要是将一些与核心业务逻辑模块无关的功能抽离出来,这些功能通常包括日志统计,安全控制,或者是异常处理等等。
我们要做的就是拓展Function.prototype来“动态植入”到业务的逻辑模块儿中,保持业务逻辑的纯净和高内聚。
现在我们有一个函数
var myFunc = function(){
console.log(1);
}
myFunc(); //1
那我们如何植入一个函数,让他在这个函数执行之前执行呢?
现在我们来拓展一个before函数。
var myFunc = function(){
console.log(1);
}
Function.prototype.before = function(fn){
var _this = this; //用来保存调用这个函数的引用,如myFunc调用此函数,则_this指向myFunc
return function(){ //返回一个函数,相当于一个代理函数,也就是说,这里包含了原函数和新函数,原函数指的是myFunc,新函数指的是fn
fn.apply(this,arguments); //修正this的指向,将this指针指向fn,将myFunc接收的参数传给fn处理。
return _this.apply(this,arguments); //执行原函数
}
}
myFunc = myFunc.before(function(){
console.log(2);
});
myFunc([3,2,1]); //先输出2,再输出1
此时,我们会发现在执行myFunc这个函数之前,我们会先执行before函数里得代码。
现在我们就可以开森得用它来复用日志统计等功能模块。
当然,我们也可以把他当作一个过滤器来使用。
比如在传入得时候,传入得参数先用sort函数排序(注意:sort排序并不稳定):
var myFunc = function(arr){
console.log(1);
console.log(arr); //输出 [1, 2, 2, 3, 4, 6, 7]
}
Function.prototype.before = function(fn){
var _this = this; //用来保存调用这个函数的引用,如myFunc调用此函数,则_this指向myFunc
return function(){ //返回一个函数,相当于一个代理函数,也就是说,这里包含了原函数和新函数,原函数指的是myFunc,新函数指的是fn
fn.apply(this,arguments); //修正this的指向,将this指针指向fn,将myFunc接收的参数传给fn处理。
return _this.apply(this,arguments); //执行原函数
}
}
myFunc = myFunc.before(function(arr){
console.log(2);
console.log(arr); //输出 [3, 2, 1, 6, 2, 7, 4]
arr.sort();
});
myFunc([3,2,1,6,2,7,4]); //先输出2,再输出1
写出了一个before了,那么after也简单了:
var myFunc = function(arr){
console.log(1);
console.log(arr); //输出 [1, 2, 2, 3, 4, 6, 7]
}
Function.prototype.before = function(fn){
var _this = this; //用来保存调用这个函数的引用,如myFunc调用此函数,则_this指向myFunc
return function(){ //返回一个函数,相当于一个代理函数,也就是说,这里包含了原函数和新函数,原函数指的是myFunc,新函数指的是fn
fn.apply(this,arguments); //修正this的指向,将this指针指向fn,将myFunc接收的参数传给fn处理。
return _this.apply(this,arguments); //执行原函数
}
}
Function.prototype.after = function(fn){
var _this = this;
return function(){
var r = _this.apply(this,arguments); //先执行原函数,也就是myFunc
fn.apply(this,arguments); //再执行新函数
return r;
}
}
myFunc = myFunc.before(function(arr){
console.log(2);
console.log(arr); //输出 [3, 2, 1, 6, 2, 7, 4]
arr.sort();
}).after(function(arr){
console.log(3);
});
myFunc([3,2,1,6,2,7,4]); //先输出2,再输出1,最后输出3
好了,我们在全局植入了这两个函数之后,以后都可以开心的直接在别的函数后面.before().after()了。
通过拓展Function.prototype实现一个AOP的更多相关文章
- JS魔法堂:再次认识Function.prototype.call
一.前言 大家先预计一下以下四个函数调用的结果吧! var test = function(){ console.log('hello w ...
- 认识Function.prototype.call
一.前言 大家先预计一下以下四个函数调用的结果吧! var test = function(){ console.log('hello w ...
- 为什么Object.prototype在Function的原型链上与Function.prototype在Object的原型链上都为true
关于javascript的原型链有一个问题我一直很疑惑:为什么 Function instanceof Object 与 Object instanceof Function都为true呢? Func ...
- 一个简易版的Function.prototype.bind实现
重新看<JavaScript设计模式与开发实践>一书,第32页发现个简易版的Function.prototype.bind实现,非常容易理解,记录在这了. Function.prototy ...
- Function.prototype.toString 的使用技巧
Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...
- Object.prototype和Function.prototype一些常用方法
Object.prototype 方法: hasOwnProperty 概念:用来判断一个对象中的某一个属性是否是自己提供的(主要是判断属性是原型继承还是自己提供的) 语法:对象.hasOwnProp ...
- Object.prototype 与 Function.prototype 与 instanceof 运算符
方法: hasOwnProperty isPrototypeOf propertyIsEnumerable hasOwnProperty 该方法用来判断一个对象中的某一个属性是否是自己提供的( 住要用 ...
- 一起Polyfill系列:Function.prototype.bind的四个阶段
昨天边参考es5-shim边自己实现Function.prototype.bind,发现有不少以前忽视了的地方,这里就作为一个小总结吧. 一.Function.prototype.bind的作用 其实 ...
- Function.prototype.bind接口浅析
本文大部分内容翻译自 MDN内容, 翻译内容经过自己的理解. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glo ...
随机推荐
- 陈远波(java)--Git 入门
本章节讲解思路:1.在Git hup官网注册一个Git账号:2.下载git bash管理工具 3.在git bash上绑定GitHup账号密码: 一:进入GitHup官网:https://githu ...
- codeforces 671D Roads in Yusland & hdu 5293 Tree chain problem
dp dp优化 dfs序 线段树 算是一个套路.可以处理在树上取链的问题.
- 阿里八八Alpha阶段Scrum(3/12)
今日进度 叶文滔: 实现了悬浮按钮的拖动. 问题困难:第三方库调入不成功,多级悬浮按钮的实现仍未完成. 刘晓: 完成注册.修改密码的UI部分,创建了注册Activity,修改密码Activity. 问 ...
- saxbuilder用法
xml为我们在网络交换数据带来很大方便,在java中可以使用saxbuilder来操作xml格式文件,下面介绍一下saxbuilder的常用方法. import org.jdom.Document; ...
- 如何将XML文件导入Excel中
如下图所示为一个规范的XML文件,在Excel中可以将规范的XML文件导入到Excel成为规范的表格.具体有如下几种方法: 工具/原料 Excel 方法/步骤 单击“数据”选项卡下的“ ...
- python提示警告InsecureRequestWarning
在Python3中使用以下代码报错: import requests response = requests.get(url='', verify=False) 错误代码如下: InsecureReq ...
- 使用docker-compose运行Django
1.新建空目录 2.进入该目录新建Dockerfile文件,并在该Dockerfile文件添加如下内容 FROM python:3 ENV PYTHONUNBUFFERED 1 RUN mkdir / ...
- 学习Kali Linux必须知道的几点
Kali Linux 在渗透测试和白帽子方面是业界领先的 Linux 发行版.默认情况下,该发行版附带了大量入侵和渗透的工具和软件,并且在全世界都得到了广泛认可.即使在那些甚至可能不知道 Linux ...
- springbatch入门练习(第一篇)
先搞懂几个概念 Job Respository: 作业仓库,负责Job.Step执行过程中的状态保存 Job launcher: 作业调度器,提供执行Job的入口 Job:作业,由多个step组成,封 ...
- JAVA框架 SpringMVC RequestMapping讲解
一.窄化请求映射 在class上做RequestMapping注解. 好处:避免在同一个项目中和其他人的url重复,出现请求混乱问题,便于管理. @Controller @RequestMapping ...