装饰器语法
Nov 23, 2021
# ES6
# 配置
# babel安装
shell
yarn add @babel/cli @babel/core @babel/preset-env -D
Babel官方的三个包,作用如下:
- @babel/cli是Babel命令行转码工具,使用命令行进行Babel转码就需要安装它。
- @babel/core核心包,@babel/cli依赖@babel/core。
- @babel/preset-env这个npm包提供了ES6转换ES5的语法转换规则,需要在Babel配置文件里指定使用它。如果不使用的话,也可以完成转码,但转码后的代码仍然是ES6的,相当于没有转码。
# babel装饰器插件安装
shell
yarn add @babel/plugin-proposal-decorators -D
# 配置文件
json
// .babelrc
{
"presets": ["@babel/env"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
# 命令
# 转码
shell
npx babel index.js -o bundle.js
# 监听
shell
npx babel index.js --watch --out-file bundle.js
# 装饰器
装饰器(Decorator)是一种与类(class)相关的语法,是一种函数,写成@函数名
。它可以放在类和类方法的定义前面。
# 类装饰器
装饰器可以用来装饰整个类。
js
@log('hello')
class MyClass { }
function log(message) {
return function(target) {
// prototype上添加一个logger方法
target.prototype.logger = () => `${message},${target.name} 被调用`;
}
}
const test = new MyClass()
test.logger(); // hello,MyClass 被调用
装饰器是一个对类进行处理的函数。装饰器函数的第一个参数,就是所要装饰的目标类。装饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,装饰器能在编译阶段运行代码。也就是说,装饰器本质就是编译时执行的函数。
# 类成员装饰器
类成员装饰器应用于类中的单个成员。这些成员可以是属性、方法、getter或setter,装饰器函数接受 3 个输入参数:
target
- 成员所在的类。name
- 类成员的名称。descriptor
- 成员描述符。
# 只读
js
// 只读
class Person {
constructor() {}
@readonly;
say() {
console.log("hello world");
}
}
function readonly(target, name, descriptor) {
// 修改属性描述符为不可写
descriptor.writable = false;
}
const person = new Person();
// Uncaught TypeError: Cannot assign to read only property 'say' of object '#<Person>'
person.say = function () {
console.log("test");
}
# 埋点分析
js
// 埋点分析
class AD {
@log("show")
show() {
console.log("ad is show");
}
@log("click")
click() {
console.log("ad is click");
}
}
function log(type) {
return function(target, name, descriptor) {
const origin = descriptor.value;
if (typeof origin === "function") {
// 装饰后的方法
descriptor.value = (...args) => {
// 执行原函数
origin.apply(target, args);
// 装饰操作
console.log(type);
};
}
};
}
const ad = new AD();
ad.show();
// ad is show
// show
ad.click();
// ad is click
// click
# TS装饰器补充
参考新版 TS 装饰器:阮一峰 TypeScript 装饰器,这是在2022年通过成为标准的。但是在此之前,TypeScript 早在2014年就支持装饰器,不过使用的是旧语法。装饰器的旧语法与标准语法,有相当大的差异。旧语法以后会被淘汰,但是目前大量现有项目依然在使用它。