这篇文章主要通过一些案例理解装饰器的使用。
babel配置
开始之前,需要准备好编译所需的配置环境,安装对应的babel
依赖包。
首先,控制台执行 npm init -y
在根目录下生成 package.json
文件。
接着下载babel
所需的依赖包:
npm install @babel/cli @babel/core @babel/preset-env -D
babel
提供了编译装饰器和类所需的两个插件:
接着下载这两个插件:
npm install @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
下载完成后,package.json
里面会有对应的版本依赖:
"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/plugin-proposal-decorators": "^7.10.5",
"@babel/plugin-proposal-class-properties": "^7.10.4"
}
接着编写babel
配置脚本,新建.babelrc
文件,输入以下配置:
{
"presets": ["@babel/preset-env"],
"plugins": [
["@babel/plugin-proposal-decorators",{"legacy": true}],
["@babel/plugin-proposal-class-properties",{"loose": true}]
]
}
这里没有使用webpack
,直接用babel
自带的命令编译我们的文件,在package.json
中新增start
命令:
"scripts": {
"start": "npx babel app.js -o index.js -w"
}
-w
表示监听文件变化,文件发生改变就会执行编译,-o
表示生产后的文件名
类装饰器
新建app.js
,控制台执行npm start
命令就可以开始我们的测试了,下面的代码都可以在app.js
中修改。
新增方法
通过装饰器给构造函数新增原型方法:
function flag(constructor) {
constructor.prototype.getName = function () {
return this.name;
};
}
@flag
class Animal {
constructor(name) {
this.name = name;
}
sayHi() {
// this.getName 通过flag新增
console.log(this.getName() + " say:'hi'");
}
}
let monkey = new Animal("monkey");
monkey.sayHi();
传参
装饰器也可以传参,有点面向切面编程(AOP)的味道了,具体方法如下:
function flag(params) {
console.log(params);
return (constructor) => {
constructor.prototype.getName = function () {
return this.name;
};
};
}
@flag({ specie: "mammal" })
class Animal {
constructor(name) {
this.name = name;
}
sayHi() {
console.log(this.getName() + " say:'hi'");
}
}
方法装饰器
函数方法也能添加装饰器,而且更能体现切片编程的思想,效果如下:
function flag(constructor) {
constructor.prototype.getName = function () {
return this.name;
};
}
function before(target, property, descripot) {
let oldMthod = descripot.value; // descripot.value获取旧方法
// 重写方法
descripot.value = function () {
console.log("before exect"); // 执行前先做的事
oldMthod.call(this, ...arguments); // 执行真正的方法
};
}
@flag
class Animal {
constructor(name) {
this.name = name;
}
@before
sayHi() {
console.log(this.getName() + " say:'hi'");
}
}
let monkey = new Animal("monkey");
monkey.sayHi(); // 控制台会打印出: before exect
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。