TypeScript 的装饰器有哪些?

JS装饰器未入正式标准,TypeScript基于第一版实现了实验性质的装饰器特性,不少第三方库已使用。文中介绍了TS中类装饰器、方法装饰器、属性装饰器等的使用,指出其可做功能增强,编译成JS后是语法糖。最后还提及分享JS与ES笔记。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 // 100 

可以看到上面代码中,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 // 50 

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

方法装饰器

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

  • target:类或者类的原型对象,下面的代码拿到的就是 Watermelon.prototype。如果是给 static 标识的方法加装饰,拿到的就是类;* prop:方法名,下面代码拿到的是 "say" 字符串;* descriptor:该 prop 的描述符,我们可以直接修改这个对象,然后这个对象会被装饰器重新应用到这个属性上。```
    // 方法装饰器
    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 // 18 

上面代码将 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 会丢掉这些装饰器标记,本质其实是语法糖。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值