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. 【第一次玩Travis CI】终于弄好了我的马鸭

    真是不容易,我都要哭了.熬了半天终于弄完了!! 终于可以坐这儿挺会小曲,写写感受了. 作为一个程序写的不咋滴的程序员,倒是特别喜欢写博客,也是绝了. 高三的时候,用OneNote,后来转到Lofter ...

  2. from urllib.request import urlopen

    from urllib.request impor urlopen      (负责打开浏览url内的html 文本) re.compile(r'alex(?P<name>\d+)and' ...

  3. SDN2017 第四次实验作业

    实验目的 1.使用图形化界面搭建拓扑如下并连接控制器 2.使用python脚本搭建拓扑如下并通过命令行连接控制器 3.使用任一种方法搭建拓扑连接控制器后下发流表 实验步骤 建立以下拓扑,并连接上ODL ...

  4. FIO_工具_专业

    一.FIO工具安装: 1.查看fio是否安装 [root@localhost /]#rpm –qa|grep fio 2.源码安装(推荐) 官网地址:http://freecode.com/proje ...

  5. 3.Dubbo2.5.3快速启动Hello World

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.服务提供者 (1)工程目录 (2)接口代码 HelloService.java package cn.lj ...

  6. 13.3SolrCloud集群使用手册之Zookeeper指令

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.upconfig java -classpath .:/home/solr/cloud/lib/* org ...

  7. HTML5API之获取地理位置详解

    在使用地理位置API之前先来了解一下什么是经度和纬度以及地理位置获取的原理 首先经度指的是南北极的连接线,纬度指的是东西的连接线 地理位置的获取原理是通过IP地址(基于ISP记录,能够知道这个IP地址 ...

  8. 【洛谷】【最小生成树】P1195 口袋的天空

    [题目背景:] 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. [题目描述:] 给你云朵的个数N,再给你M个关系,表示哪些 ...

  9. InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClas...

    如果 你的项目中使用了注解插件 比如butterknife   升级3.1之后打包编译  出现以下错误提示 InnerClass annotations are missing correspondi ...

  10. Python基础(9)——类

    类的语法 类的定义 class Dog(object): print("hello,I am a dog!") d = Dog() #实例化这个类, #此时的d就是类Dog的实例化 ...