通过拓展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 ...
随机推荐
- 35_张孝祥Java高新技术_为注解增加各种属性
注解的作用之所以那么强大,就是因为它有属性 注解很像接口,属性很像方法. 什么是注解的属性 一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就不是.如果还想区分出事传智播客 ...
- TiDB数据库 mydumper与loader导入数据
从mysql导出数据最好的方法是使用tidb官方的工具mydumper. 导入tidb最好的方法是使用loader工具,大概19.4G每小时的速度. 详细的步骤可以参考官网:https://pingc ...
- TiDB数据库集群安装以及注意事项
今天尝试安装tidb集群.详细的安装步骤我们参考:https://pingcap.com/docs-cn/op-guide/ansible-deployment/ . 不过安装之前需要一些注意事项. ...
- 乘风破浪:LeetCode真题_026_Remove Duplicates from Sorted Array
乘风破浪:LeetCode真题_026_Remove Duplicates from Sorted Array 一.前言 我们这次的实验是去除重复的有序数组元素,有大体两种算法. 二.Remo ...
- node.js 笔记一
现在地址:http://nodejs.org/download/ 我的机器是windows的,选择的文件是,是编译后的版本:Windows Installer (.msi) 32-bit examp ...
- 【Alpha 冲刺】 6/12
今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 建立数据库 未完成 表结构文档已设计好,服务器mysql刚配置完成,但是,SpringMVC框架还没有熟络,不清楚如何使用该框架去 ...
- React-Native 真机调试踩坑指南
继上一篇基础安装踩坑继续我们的踩坑之旅,备注一下以下仅针对Mac环境-- 安卓 1.adb 找不到命令? Adb的全称为Android Debug Bridge,就是起到调试桥的作用,真机调试安卓必备 ...
- Redis系列二:reids介绍
一.什么是redis.redis有哪些特性.redis有哪些应用场景.redis的版本 1. 什么是redis redis是一种基于键值对(key-value)数据库,其中value可以为string ...
- BZOJ4245:[ONTAK2015]OR-XOR(贪心)
Description 给定一个长度为n的序列a[1],a[2],...,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的异或和,则总费用为c[1] or c[2] or ...
- Android7.0调用系统相机拍照、读取系统相册照片+CropImageView剪裁照片
Android手机拍照.剪裁,并非那么简单 简书地址:[我的简书–T9的第三个三角] 前言 项目中,基本都有用户自定义头像或自定义背景的功能,实现方法一般都是调用系统相机–拍照,或者系统相册–选择照片 ...