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的更多相关文章

  1. JS魔法堂:再次认识Function.prototype.call

    一.前言                                大家先预计一下以下四个函数调用的结果吧! var test = function(){ console.log('hello w ...

  2. 认识Function.prototype.call

    一.前言                                大家先预计一下以下四个函数调用的结果吧! var test = function(){ console.log('hello w ...

  3. 为什么Object.prototype在Function的原型链上与Function.prototype在Object的原型链上都为true

    关于javascript的原型链有一个问题我一直很疑惑:为什么 Function instanceof Object 与 Object instanceof Function都为true呢? Func ...

  4. 一个简易版的Function.prototype.bind实现

    重新看<JavaScript设计模式与开发实践>一书,第32页发现个简易版的Function.prototype.bind实现,非常容易理解,记录在这了. Function.prototy ...

  5. Function.prototype.toString 的使用技巧

    Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...

  6. Object.prototype和Function.prototype一些常用方法

    Object.prototype 方法: hasOwnProperty 概念:用来判断一个对象中的某一个属性是否是自己提供的(主要是判断属性是原型继承还是自己提供的) 语法:对象.hasOwnProp ...

  7. Object.prototype 与 Function.prototype 与 instanceof 运算符

    方法: hasOwnProperty isPrototypeOf propertyIsEnumerable hasOwnProperty 该方法用来判断一个对象中的某一个属性是否是自己提供的( 住要用 ...

  8. 一起Polyfill系列:Function.prototype.bind的四个阶段

    昨天边参考es5-shim边自己实现Function.prototype.bind,发现有不少以前忽视了的地方,这里就作为一个小总结吧. 一.Function.prototype.bind的作用 其实 ...

  9. Function.prototype.bind接口浅析

    本文大部分内容翻译自 MDN内容, 翻译内容经过自己的理解. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glo ...

随机推荐

  1. Local policy - User rights assignment 对照表

    "SeCreateTokenPrivilege"  --> "Create a token object" "SeAssignPrimaryTo ...

  2. Oracle_spatial的空间索引

    空间索引 1.空间索引的创建 1)创建索引之前总是要为空间层插入元数据 2)如果之前创建的索引失败了,必须先删除才能创建 Drop index customers_sidx; 创建索引: Create ...

  3. WorldWind源码剖析系列:设置类SettingsBase

    PluginSDK中的星球设置类WorldSettings 和WorldWind.程序设置类WorldWindSettings均继承自父类SettingsBase.类图如下所示.其中父类Setting ...

  4. nginx配置收集

    同个服务,分别读取不同借口 location /xibao/service_api/ { if ($request_uri ~ ^/xibao/(.*)) { set $xibao_data_url ...

  5. 在Node.js中操作文件系统(一)

    在Node.js中操作文件系统 在Node.js中,使用fs模块来实现所有有关文件及目录的创建,写入及删除操作.在fs模块中,所有对文件及目录的操作都可以使用同步与异步这两种方法.比如在执行读文件操作 ...

  6. 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动

    引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...

  7. 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 ...

  8. jQuery的extend和fn.extend理解

    参考网址:http://www.cnblogs.com/yuanyuan/archive/2011/02/23/1963287.html http://www.cnblogs.com/xuxiuyu/ ...

  9. HUE配置HIVE

    HIVE配置 修改hue.ini配置文件 [beeswax] hive_server_host=node1 hive_server_port= hive_conf_dir=/usr/hive-/con ...

  10. ABC Tech Day(2018.08.11)

    时间:2018.07.24地点:北京中关村创业大街车库咖啡