当你不得不在别人的代码之上添加功能时,你该怎么做?
什么是装饰者?
定义:不改变对象自身的基础上,在运行过程中动态地给对象添加功能。
通俗点说,通常是基于一个函数,装饰之后生成另外一个函数。
装饰者最大的特点就是不改变原函数,所以它的用途主要在原函数上添加功能。
装饰者的两种用法
保存原引用的改写
window.onload = function() {
console.log(1);
console.log(this.a) // 此处 this指向 window
}
var _onload = window.onload || function() {};
window.onload = function() {
_onload();
console.log(2);
}
该种方式看上去行,但是存在两个问题:
- 1、存在临时变量,但装饰的方法多了之后,就非常冗余。
- 2、当原函数里面存在 this指向时,就出错了。
AOP装饰函数
AOP(面向切面编程):主要作用是将跟业务逻辑无关的功能抽取出来,再动态掺入业务逻辑模块。与业务逻辑无关的功能通常有:日志统计、埋点、异常处理等。
当然,这只是一个思想,并不一定完全遵守抽取的是与业务逻辑无关的功能,关键在于,在函数某个部分插入某个功能,就像把面包切成好几块,然后可以在切面添加不同的佐料一般。
装饰者模式其实就是采用了 AOP思想,如下是通过原型的方式实现装饰者模式:
// 以下两种函数均为高阶函数。高阶函数的定义是,参数是函数,或者返回值是函数
Function.prototype.before = function (beforeFn) {
let _self = this
return function () {
beforeFn.apply(this, arguments)
return _self.apply(this, arguments)
}
}
Function.prototype.after = function (afterFn) {
let _self = this
return function () {
let val = _self.apply(this, arguments)
afterFn.apply(this, arguments)
return val
}
}
以上装饰者模式实现了不改变原函数功能的情况下,动态添加新的功能。该模式常见适用场景:
- 原代码复杂,不想修改原代码的同时又增加新的功能
- 在原代码之前添加埋点、校验等功能时。
Gitalking ...
Be the first guy leaving a comment!