通过拓展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 ...
随机推荐
- Local policy - User rights assignment 对照表
"SeCreateTokenPrivilege" --> "Create a token object" "SeAssignPrimaryTo ...
- Oracle_spatial的空间索引
空间索引 1.空间索引的创建 1)创建索引之前总是要为空间层插入元数据 2)如果之前创建的索引失败了,必须先删除才能创建 Drop index customers_sidx; 创建索引: Create ...
- WorldWind源码剖析系列:设置类SettingsBase
PluginSDK中的星球设置类WorldSettings 和WorldWind.程序设置类WorldWindSettings均继承自父类SettingsBase.类图如下所示.其中父类Setting ...
- nginx配置收集
同个服务,分别读取不同借口 location /xibao/service_api/ { if ($request_uri ~ ^/xibao/(.*)) { set $xibao_data_url ...
- 在Node.js中操作文件系统(一)
在Node.js中操作文件系统 在Node.js中,使用fs模块来实现所有有关文件及目录的创建,写入及删除操作.在fs模块中,所有对文件及目录的操作都可以使用同步与异步这两种方法.比如在执行读文件操作 ...
- 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动
引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...
- openstack vm ping 114.114.114.114
route add -net 0.0.0.0 netmask 0.0.0.0 gateway 192.168.0.131 route del -net 0.0.0.0 netmask 0.0.0.0 ...
- jQuery的extend和fn.extend理解
参考网址:http://www.cnblogs.com/yuanyuan/archive/2011/02/23/1963287.html http://www.cnblogs.com/xuxiuyu/ ...
- HUE配置HIVE
HIVE配置 修改hue.ini配置文件 [beeswax] hive_server_host=node1 hive_server_port= hive_conf_dir=/usr/hive-/con ...
- ABC Tech Day(2018.08.11)
时间:2018.07.24地点:北京中关村创业大街车库咖啡