JavaScript中AOP的应用

栏目: Java · 发布时间: 5年前

内容简介:AOP (Aspect Oriented Programming) ,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是函数式编程的一种衍生,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。使用过java spring的同学一定知道,其内分为三种通知,下面我们分别在js调用方法时实现这三种通知:

AOP (Aspect Oriented Programming) ,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是函数式编程的一种衍生,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

JavaScript中AOP的应用

2. 基础实现

使用过java spring的同学一定知道,其内分为三种通知, before (前置通知)、 after (后置通知)、 around (环绕通知)。

下面我们分别在js调用方法时实现这三种通知:

before(前置通知)

顾名思义,就是在函数调用前执行

Function.prototype.before = function (beforefun) {
  var _orgin = this;    // 保存原函数引用
  return function () { // 返回包含了原函数和新函数的"代理函数"
    beforefun.apply(this, arguments); // 执行新函数,修正this
    return _orgin.apply(this, arguments); // 执行原函数
  }
};

var originFun = function(val){
  console.log('原型函数: '+val);
}

var newFun = originFun.before(function(){
  // 传入函数调用前处理方法
  console.log('before: ' + new Date().getTime())
})

newFun("测试前置通知");

// 调用结果
// before: 1557047939699
// 原型函数: 测试前置通知
复制代码

after(后置通知)

与before正相反,在函数调用后执行

Function.prototype.after = function (afterfun) {
  var _orgin = this;    // 保存原函数引用
  return function () { // 返回包含了原函数和新函数的"代理函数"
    var ret = _orgin.apply(this, arguments); // 执行原函数
    afterfun.apply(this, arguments); // 执行新函数,修正this
    return ret;
  }
};

var originFun = function(val){
  console.log('原型函数: '+val);
}

var newFun = originFun.after(function(){
  // 传入函数调用前处理方法
  console.log('after: ' + new Date().getTime())
})

newFun("测试后置通知");

// 调用结果
// 原型函数: 测试前置通知
// after: 1557047997647
复制代码

around(环绕通知)

在方法执行前后分别执行

// 利用前面的before、after方法实现
Function.prototype.around = function(beforeFun, afterFun) {
	var _orgin = this;
	return function() {
		return _orgin.before(beforeFun).after(afterFun).apply(this, arguments);
	}
}
复制代码

3. AOP遇到修饰器

JS在ES7的提案中终于增加了修饰器(Decorator)函数,它是用来修改类的行为,但是现在浏览器都不支持,需要使用Babel进行转换,当AOP与修饰器结合后,又会给我们带来什么呢?

日志记录

通过AOP与修饰器的结合会很方便的进行日志的记录或者函数执行时间的记录

class Person {
  @log
  say(nick) {
    return `hi ${nick}`;
  }
}

function log(target, name, decriptor){
  var _origin = descriptor.value;
  descriptor.value = function(){
    console.log(`Calling ${name} with `, argumants);
    return _origin.apply(null, arguments);
  };

  return descriptor;
}

var person = new Person();
person.say('小明');
复制代码

判断用户登录状态

class User {
  @checkLogin
  getUserInfo() {
    console.log('获取用户信息')
  }
}

// 检查用户是否登录
function checkLogin(target, name, descriptor) {
  let method = descriptor.value
  descriptor.value = function (...args) {
    // 校验方法,假设这里可以获取到用户名/密码
    if (validate(args)) {
      method.apply(this, args)
    } else {
      console.log('没有登录,即将跳转到登录页面...')
    }
  }
}

let user = new User()
user.getUserInfo()
复制代码

4. React中的AOP

在react中使用AOP思想的典型就是高阶组件(HOC),请看下面的例子

function HOCComp(WrappedComponent){
  return class HOC extends Component {
    render(){
      const newProps = {param: 'HOC'};
      return <div>
        <WrappedComponent {...this.props} {...newProps}/>
      </div>
    }
  }
}

@HOCComp
class OriginComponent extends Component {
  render(){
    return <div>这是原始组件{this.props.param}</div>
  }
}
复制代码

上面例子中在HOCComp中定义新的props,并传入子组件中。我们也可以对OriginComponent组件中的一些props进行加工,或对OriginComponent外层进行再次包装。从而不必去修改内部组件,保持了功能上的解耦。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

运营笔记

运营笔记

类延昊 / 天津人民版社 / 2016-12-1 / CNY 39.80

运营是入门浅但学问深的行当。一个入门很久的人不见得能在11年内爬到塔尖,同样一个初入龙门的人占据高位也不见得非用11年。 到底该怎么做运营?如何做运营才不至于让自己忙死累死甚至茫然不知所措?如何和用户进行有效沟通?如何把握住处于塔尖20%的核心用户?如何强敌逼阵时快速找到突破口?如何挤破头皮提高转化率? 在这本书里,类类以自己常年战斗在一线摸爬滚打的经验给予了有效而真诚的解答。一起来看看 《运营笔记》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具