var func = function () {
console.log("2")
}
Function.prototype.before = function (beforefn) {
//待补全的函数
}
Function.prototype.after = function (afterfn) {
//待补全的函数
};
func=func.before(function () {
console.log("1");
}).after(function () { //此时,after函数中的this指向func.before
console.log("3");
})();

实现输出:

这是我在笔试中遇到的题目,结束后,下来查了查,发现是js的一种模式——AOP(面向切面编程)。

什么是AOP?

AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, 再通过“动态织入”的方式掺入业务逻辑模块中。

大致了解了其作用后,开始破解题目

Function.prototype.before=function(fn){
let _self=this; //this==Function.prototype
return function beforeFunc(){
fn.apply(this,arguments);
_self.apply(this,arguments);
// return _self.apply(this,arguments); //若func有返回值
}
}
Function.prototype.after=function(fn){
let _beforeFunc=this;
return function afterFunc(){
_beforeFunc.apply(this,arguments);
// let res=_beforeFunc.apply(this.argumens);
fn.apply(this,arguments);
// return res
}
}

结合最初的题目,讲解原理:

  • 在 func.before 执行时,内部的 this 当前指向 func 函数,使用临时变量 __self 保存.令方法返回一个闭包,为方便理解闭包命名为 beforeFunc(可以是匿名的) 。

  • beforeClosure 被返回后, after 方法的调用变成了 beforeFunc.after,
    此时,after内部 this 当前指向 beforeFunc,使用临时变量 __beforeClosure 保存。令方法返回一个闭包,命名为 afterFunc。

  • 调用 afterFunc(),afterClosure 内部首先调用 beforeFunc 闭包,并把当前 this 和 参数传入 beforeFunc。

  • beforeFunc内部首先调用参数 fn, 执行console.log(1) ,然后__self换成func方法,console.log(2),调用过程中的 this 和 arguments 都是 beforeFunc调用时传进来的,与 afterFunc 是一致的。

  • beforeFunc执行完毕,执行afterFunc 的第二步(after 参数fn中的函数console.log(3))
  • 若改过程有返回值:beforeFunc执行完毕,返回func的返回值,回到 afterFunc 的第一步,result接收 func函数的返回值,然后执行 after 参数中的函数 ,最后把 result 返回。

over!

javascript AOP(面向切面编程)的更多相关文章

  1. Javascript aop(面向切面编程)之around(环绕)

    Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知).after(后置通知).around(环绕通知),用过spring的同学肯定对它非常熟悉,而在js中,AOP是一个被 ...

  2. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

  3. AOP面向切面编程的四种实现

     一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...

  4. Method Swizzling和AOP(面向切面编程)实践

    Method Swizzling和AOP(面向切面编程)实践 参考: http://www.cocoachina.com/ios/20150120/10959.html 上一篇介绍了 Objectiv ...

  5. [转] AOP面向切面编程

    AOP面向切面编程 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  6. C# AOP 面向切面编程之 调用拦截

    有时候我们需要在代码中对方法调用进行拦截,并修改参数和返回值,这种操作叫做AOP(面向切面编程) 不过需要注意的是,AOP的效率很慢,在需要高效率场合慎用. 以下是C#的AOP方法: 首先建立一个控制 ...

  7. 【原创】Android AOP面向切面编程AspectJ

    一.背景: 在项目开发中,对 App 客户端重构后,发现用于统计用户行为的友盟统计代码和用户行为日志记录代码分散在各业务模块中,比如在视频模块,要想实现对用户对监控点的实时预览和远程回放行为进行统计, ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  9. 论AOP面向切面编程思想

    原创: eleven 原文:https://mp.weixin.qq.com/s/8klfhCkagOxlF1R0qfZsgg [前言] AOP(Aspect-Oriented Programming ...

随机推荐

  1. MySQL SELECT练习题*28

    -- (1)用子查询查询员工“张小娟”所做的订单信息. SELECT * FROM order_master WHERE saler_no = ( SELECT employee_no FROM em ...

  2. mysql备份与恢复-xtracebackup

    因为percona打算放弃使用innobackupex备份工具,因此我们这里也说明一下innobackupex的兄弟工具xtraceback工具的使用 这个工具的安装可以参考上面的一些博文,上面详细说 ...

  3. Golang生成区间随机整数

    package main import ( "fmt" "math/rand" "time" ) func main() { rand.Se ...

  4. Golang的值类型和引用类型的范围、存储区域、区别

    常见的值类型和引用类型分别有哪些? 值类型:基本数据类型 int 系列, float 系列, bool, string .数组和结构体struct,使用这些类型的变量直接指向存在内存中的值,值类型的变 ...

  5. Vue小案例 之 商品管理------添加商品

    进行添加button,以及商品列表的创建 html: <div class="form-btn"> <button>确认添加</button> ...

  6. Hashtable与HashMap的区别

    HashMap不是线程安全的,HashTable是线程安全. HashMap允许空(null)的键和值(key),HashTable则不允许. HashMap性能优于Hashtable.

  7. zookeeper各种报错、原因及解决方法汇总(持续更新)

    [root@iZ23nn1p4mjZ zookeeper-3.4.10]# bin/zkCli.sh -server localhost:2181,localhost:2182,localhost:2 ...

  8. jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解

    jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如 ...

  9. docker 给运行的容器映射本地端口

    1.提交运行中的容器为一个镜像   (这样不会丢失在容器的各种操作) docker commit  tang     tang1 ###  tang(运行容器名称)   tang1(生成镜像名称) 2 ...

  10. NSIS+Duilib 制作Windows安装包

    转载:https://www.cnblogs.com/zzllily/articles/5443850.html 转载:https://blog.csdn.net/bruce135lee/articl ...