文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

TypeScript 的装饰器有哪些?

2024-12-01 15:04

关注

大家好,我是前端西瓜哥。

JS 的装饰器还在提案中(提案了好久),还没进入正式标准,掌握半成品实在性价比不高。

但装饰器实在是太强了,TypeScript 还是基于第一版实现了自己的装饰器特性,并标明为实验性质,让大家能够早早地用上。

目前也不少知名的第三方库(比如 Nest.js)使用了 TS 的装饰器,还是有必要学习的。

但是呢,TS 的装饰器实现已经和 ECMAScript 的装饰器提案越走越远。

但因为 TS 装饰器被不少知名的第三方库使用,我们可能还是得使用和标准不同的装饰器。

以后两种装饰器的实现就要打架了,实在是太乱了,库作者大概要吐了。

TS 中实现的装饰器有:

  1. 类装饰器
  2. 方法装饰器
  3. 访问器装饰器
  4. 属性装饰器
  5. 参数装饰器

在使用类装饰器前,你需要在 tsconfig.json 中启用实验性的装饰器配置:

{
"compilerOptions": {
"experimentalDecorators": true
}
}

装饰器其实是一个函数,需要在被类使用前声明。因为 类声明后立刻就会执行修饰器,所以如果没有提前声明,就会报错。

类装饰器

类装饰器是一个函数,它可以在 class 声明时拿到 class,然后对 class 进行一些操作。

给一个类应用类装饰器的方式是:在类名的上一行加上 @<装饰器名>。

function changeDefaultPrice(constructor: Function & {defaultPrice: number}) {
constructor.defaultPrice = 100;
}
@changeDefaultPrice
class Watermelon {
static defaultPrice = 9;
}
Watermelon.defaultPrice

可以看到上面代码中,Watermelon 类有个静态属性 defaultPrice,值为 9,表示默认西瓜只要 9 块钱。

太便宜了,于是我实现了个 changeDefaultPrice 装饰器,能够从函数参数中拿到类,并将其修改为 100 块。

有时候,我们希望可以修改为自定义价格。这时候我们可以使用 装饰器工厂函数。

所谓装饰器工厂函数,就是一个返回装饰器函数的函数。通过它,我们就能利用闭包注入变量。​

function changeDefaultPrice(price = 100) {
return function (constructor: Function & { defaultPrice: number }) {
constructor.defaultPrice = price;
};
}
@changeDefaultPrice(50)
class Watermelon {
static defaultPrice = 9;
}
Watermelon.defaultPrice

装饰器工厂函数不只可以用在类装饰器中,还可以用在其他类型的装饰器中。

方法装饰器

方法装饰器可以接受的参数有:

function changeMethod(
target: any,
prop: string | symbol,
descriptor: PropertyDescriptor
) {
descriptor.value = function () {
console.log("我没裂开");
};
}
class Watermelon {
@changeMethod
say() {
console.log("我裂开了");
}
}
const wm = new Watermelon();
wm.say();

上面代码用 changeMethod 方法装饰器重写了 Watermelon.prototype.say 方法。

如果 TS 编译没能通过,你需要再给 tsconfig.json 配置上 target,且使其大于等于 ES5 版本。默认的 ES3 版本有些 API 都不支持。

访问器装饰器

访问器装饰器,对类的 get 或 set 方法进行装饰。

和方法装饰器类似,访问器装饰器获得的参数有:

  1. target:类或类的原型对象。
  2. prop:成员名。
  3. descriptor:成员的描述符。
function doublePrice(
target: Object,
prop: string | symbol,
descriptor: PropertyDescriptor
) {
const getter = descriptor.get!;
descriptor.get = function() {
return getter.call(this) * 2;
}
}
class Watermelon {
private _price = 9;
@doublePrice
get price() {
return this._price;
}
}
const wm = new Watermelon();
wm.price

上面代码将 price 的值翻倍了。

属性装饰器

属性装饰器,顾名思义用于修饰类的属性。

属性修饰器接受的参数有:

  1. taget:类或类的原型对象。
  2. prop:属性名。
function propDeco(target: any, prop: string | symbol) {
console.log({ target, prop });
}
class Watermelon {
@propDeco
goodName = "西瓜";
}

参数装饰器

参数装饰器用于装饰函数参数,用于类构造器和方法。

参数装饰器能获得的参数有:

  1. target:类或类的原型对象。
  2. prop:函数名,或 undefined(函数为构造函数时)。
  3. paramIdx:被装饰的参数的位置。
function validatePhone(target: Object, prop: string | symbol, paramIdx: number) { 
}
class Watermelon {
constructor(a: string, @validatePhone b: string) {
console.log(a, b);
}
}

参数装饰器的一个用途是可以做参数校验,将某个索引的位置保存起来,然后再利用方法装饰器拿到描述符 descriptor,对原方法做一层校验的封装。

总结

总的看来,TS 装饰器可以在类上加一些标记,然后对应的装饰器就能拿到必要的信息(类的原型、方法名、描述符等),然后就可以做一些代理、记录信息的功能增强。

TS 装饰器最后编译成的 JS 会丢掉这些装饰器标记,本质其实是语法糖。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。

来源:前端西瓜哥内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯