【前端】你好,我叫TypeScript (五)装饰器

2025-05-29 0 21

【前端】你好,我叫TypeScript (五)装饰器

1.什么是装饰器

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性和参数上。

  • 装饰器是一个表达式
  • 表达式被执行后,返回一个函数
  • 函数的输入参数为:target,name和descriptor
  • 执行函数后,可能返回descriptor对象,用于配置target对象

装饰器使用@expression形式,expression求值后必须返回一个函数,他会在运行时被调用,被装饰的声明信息作为参数传入。

例如:

  1. //定义装饰器
  2. functiontestDecorator(target:any,key:string):void{
  3. console.log("Target:",target);
  4. console.log("key:",key);
  5. }
  6. //使用装饰器
  7. classBoat{
  8. color:string="yellow";
  9. getformattedColor():string{
  10. return`thisboatcoloris${this.color}`;
  11. }
  12. @testDecorator
  13. pilot():void{
  14. console.log("swish");
  15. }
  16. }
  17. //实例化
  18. constboat=newBoat();
  19. boat.pilot();
  20. console.log(boat.formattedColor);

运行得到:

  1. Target:{}
  2. key:pilot
  3. swish
  4. thisboatcolorisyellow

2.装饰器分类

装饰器根据其所装饰的类型分为以下一种:

若要启用实验性的装饰器特性,你必须在命令行或tsconfig.json里启用experimentalDecorators编译器选项:

命令行:

  1. tsc–targetES5–experimentalDecorators

tsconfig.json:

  1. {
  2. "compilerOptions":{
  3. "target":"ES5",
  4. "experimentalDecorators":true
  5. }
  6. }

2.1 类装饰器

装饰器用于类构造函数,进行监听、修改或替换类定义,在类声明之前进行声明(紧挨着类声明)。

切记:

  • 装饰器不能用在声明文件中(.d.ts),也不能用在任何外部上下文中。
  • 装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
  • 如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
  • 如果你要返回一个新的构造函数,你必须注意处理好原来的原型链。在运行时的装饰器调用逻辑中不会为你做这些。

装饰器声明:

  1. declaretypeClassDecorator=<TFunctionextendsFunction>(
  2. target:TFunction
  3. )=>TFunction|void;

装饰器顾名思义,就是⽤来装饰类的。它接收⼀个参数:

  • target: TFunction – 被装饰的类

栗子:

  1. //类装饰器
  2. functionclassDecorator(constructor:typeofBoat){
  3. console.log(constructor);
  4. }
  5. //使用类装饰器
  6. @classDecorator
  7. classBoat{
  8. }

运行结果:

  1. [classBoat]

2.2 方法装饰器

方法装饰器用于方法的属性描述符,可以进行监听、修改或替换方法定义,在待修饰方法声明前进行声明。方法装饰器不能用在声明文件(.d.ts),重载或者任何外部上下文中。

方法装饰器表达式会在运行时当作函数被调用,传入下列3个参数:

  • target:被装饰的类
  • key: 方法名
  • descriptor: 属性描述符

「注意:如果代码输出目标版本小于ES5,属性描述符将会是undefined。」

如果方法装饰器返回一个值,它会被用作方法的属性描述符。

举个栗子:

  1. //定义装饰器
  2. functiontestDecorator(target:any,key:string):void{
  3. console.log("Target:",target);
  4. console.log("key:",key);
  5. }
  6. functionlogError(errorMessage:string){
  7. returnfunction(target:any,key:string,desc:PropertyDescriptor){
  8. constmethod=desc.value;
  9. desc.value=function(){
  10. try{
  11. method();
  12. }catch(err){
  13. console.log(errorMessage);
  14. }
  15. }
  16. }
  17. }
  18. //使用装饰器
  19. classBoat{
  20. color:string="yellow";
  21. @testDecorator
  22. getformattedColor():string{
  23. return`thisboatcoloris${this.color}`;
  24. }
  25. @logError("Oopsboatwassunkinocean")
  26. pilot():void{
  27. thrownewError()
  28. console.log("swish");
  29. }
  30. }
  31. //实例化
  32. constboat=newBoat();
  33. boat.pilot();

运行得到:

  1. Target:{}
  2. key:formattedColor
  3. Oopsboatwassunkinocean

2.3 属性装饰器

属性装饰器属性描述符只能用来监视类中是否声明了某个名字的属性,在属性声明前进行声明。

属性装饰器表达式会在运行时当做函数进行调用,传入两个参数:

  • target: 被装饰的类
  • key: 被装饰类的属性名字

注意:属性描述符不作为参数传入属性装饰器。因为目前还没有办法在定义一个原型对象时描述一个实例属性,并且没有办法进行建议监听或修改一个属性的初始化方法。

  1. //定义装饰器
  2. functiontestDecorator(target:any,key:string):void{
  3. console.log("Target:",target);
  4. console.log("key:",key);
  5. }
  6. functionlogError(errorMessage:string){
  7. returnfunction(target:any,key:string,desc:PropertyDescriptor){
  8. constmethod=desc.value;
  9. desc.value=function(){
  10. try{
  11. method();
  12. }catch(err){
  13. console.log(errorMessage);
  14. }
  15. }
  16. }
  17. }
  18. //使用装饰器
  19. classBoat{
  20. @testDecorator
  21. color:string="yellow";
  22. //@testDecorator
  23. getformattedColor():string{
  24. return`thisboatcoloris${this.color}`;
  25. }
  26. @logError("Oopsboatwassunkinocean")
  27. pilot():void{
  28. thrownewError()
  29. console.log("swish");
  30. }
  31. }

运行结果:

  1. Target:{}
  2. key:color

2.4 参数装饰器

参数装饰器用于类构造函数或方法声明。接收三个参数:

  • target: 被装饰的类
  • key:方法名
  • index:方法中的参数索引值
  1. //定义装饰器
  2. functiontestDecorator(target:any,key:string):void{
  3. console.log("Target:",target);
  4. console.log("key:",key);
  5. }
  6. functionlogError(errorMessage:string){
  7. returnfunction(target:any,key:string,desc:PropertyDescriptor){
  8. constmethod=desc.value;
  9. desc.value=function(){
  10. try{
  11. method();
  12. }catch(err){
  13. console.log(errorMessage);
  14. }
  15. }
  16. }
  17. }
  18. //参数装饰器
  19. functionparameterDecorator(target:any,key:string,index:number){
  20. console.log(key,index);
  21. }
  22. //使用装饰器
  23. classBoat{
  24. @testDecorator
  25. color:string="yellow";
  26. //@testDecorator
  27. getformattedColor():string{
  28. return`thisboatcoloris${this.color}`;
  29. }
  30. @logError("Oopsboatwassunkinocean")
  31. pilot():void{
  32. thrownewError()
  33. console.log("swish");
  34. }
  35. fast(
  36. @parameterDecoratorspeed:string,
  37. @parameterDecoratorgenerateWake:boolean
  38. ):void{
  39. if(speed==="fast"){
  40. console.log("swish");
  41. }else{
  42. console.log("nothing");
  43. }
  44. }
  45. }

运行结果:

  1. Target:{}
  2. key:color
  3. fast1
  4. fast0

小结

我们看到装饰器很方便为我们结果了许多问题。装饰器根据其装饰的对象不同,分为:类装饰器、属性装饰器、方法装饰器、参数装饰器

原文链接:https://mp.weixin.qq.com/s/7qZjqNoo0G0lHryObCc85w

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 【前端】你好,我叫TypeScript (五)装饰器 https://www.kuaiidc.com/93276.html

相关文章

发表评论
暂无评论