作用及意义
其实使用装饰器模式就是我压根不想去关心它现有的业务逻辑是什么。我只是想对它已有的功能做个拓展,只关心拓展出来的那部分新功能如何实现。
实际工作中的运用(简单粗暴)
老板交给小明一个远古项目,告诉小明相关开发已经跑路离职,没有任何交接文档。你来给我修改下这个Low代码,添加一段你写的Low代码。
小明粗暴的写下了如下代码
function lowCode(){
console.log('大量很Low的代码')
}
function myCode(){
console.log('自己写Low代码')
}
// 将新功能与老功能组合
function moreCode(){
lowCode()
myCode()
}
moreCode()
小明看了自己写的代码,我不要当lowbe,毕竟我是会Java的前端开发工程师。于是有了下面的这段代码。
//原始的low代码
var LowCode = function () {
};
LowCode.prototype.log = function () {
console.log('大量的Low的代码');
};
//装饰类
var LowDecorator = function (lowCode) {
this.lowCode = lowCode;
}
//装饰类中的方法
LowDecorator.prototype.log = function () {
this.lowCode.log();
console.log('自己写Low代码!');
};
var lowCode = new LowCode();
lowCode = new LowDecorator(lowCode);
lowCode.log();
es6如何实现呢
class LowCode {
log() {
console.log('大量的Low的代码');
};
}
class LowDecorator {
constructor(lowCode){
this.lowCode=lowCode
}
log() {
this.lowCode.log();
console.log('自己写Low代码!');
};
}
var lowCode = new LowCode();
lowCode = new LowDecorator(lowCode);
lowCode.log();
仔细的想一想这样真的合理么,我如果想修饰一个类。需要重新构造一个类,这完全就是Java的变成思想啊。小明不是
Java工程师么前端工程师么?
class LowCode {
log() {
console.log('大量的Low的代码');
};
}
//定义修饰器方法传入一个类 返回一个修饰过类
function lowDecorator(lowCode) {
var log = lowCode.log;
lowCode.log = function () {
log();
console.log('自己写Low代码!');
};
return lowCode
}
var lowCode = lowDecorator(new LowCode())
lowCode.log();
实现before、after修饰方法
// 这一步份设计代理的概念,如果不懂得道友可以等后续的系列文章
Function.prototype.before=function (beforefn) {
var _this= this; //保存旧函数的引用
return function () { //返回包含旧函数和新函数的“代理”函数
beforefn.apply(this,arguments); //执行新函数,且保证this不被劫持,新函数接受的参数
// 也会被原封不动的传入旧函数,新函数在旧函数之前执行
return _this.apply(this,arguments);
};
};
function lowCode(){
console.log('大量很Low的代码')
}
const low = lowCode.before(function(){
console.log('写在前面的low代码')
})
low()
同理实现 after 方法
Function.prototype.after=function (afterfn) {
var _this=this;
return function () {
var ret=_this.apply(this,arguments);
afterfn.apply(this,arguments);
return ret;
};
};
function lowCode(){
console.log('大量很Low的代码')
}
const low = lowCode.after(function(){
console.log('写在后面的low代码')
})
low()
关于es7中的修饰符
在讲es7修饰符之前呢,需要先解决es7编译问题。当然是babel大法啦!
yarn //初始化
yarn add babel babel-preset-env babel-plugin-transform-decorators-legacy --dev //安装依赖
目录结构如下
├── .babelrc
├── dist
│ └── index.js
├── package.json
├── src
│ └── index.js
└── yarn.lock
.babelrc配置
{
"presets": ["env"],
"plugins": ["transform-decorators-legacy"]
}
执行命令
yarn babel src --watch --out-dir dist
修饰类
// 装饰器函数,它的第一个参数是目标类
function classDecorator(target) {
target.hasDecorator = true
return target
}
// 将装饰器“安装”到Button类上
@classDecorator
class LowCode {
}
// 验证装饰器是否生效
console.log('LowCode是否被装饰了:', LowCode.hasDecorator) //true
修饰方法
// 第一个参数目标对函数 第二个是函数名字 第三个参数 属性描述对象
// descriptor 可以理解为 Object.defineProperty
function funcDecorator(target, name, descriptor) {
let originalMethod = descriptor.value
descriptor.value = function () {
console.log('我是Func的装饰器逻辑')
return originalMethod.apply(this, arguments)
}
return descriptor
}
class Button {
@funcDecorator
onClick() {
console.log('我是Func的原有逻辑')
}
}
(new Button).onClick()
// 我是Func的装饰器逻辑
// 我是Func的原有逻辑
此处就不做过多的介绍了,有兴趣的道友建议去阅读阮一峰的ES6。我就不误人子弟做过多描述了。