前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript装饰器

TypeScript装饰器

原创
作者头像
coldPlayer
发布2023-11-15 23:33:05
1600
发布2023-11-15 23:33:05
举报

🐱个人主页:<font color="#409EFF">不叫猫先生</font> 🙋‍♂️作者简介:前端领域新星创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀! 💫系列专栏:vue3从入门到精通、TypeScript从入门到实践

📢资料领取:前端进阶资料以及文中源码可以找我免费领取

🔥社群招募:博主建立了一个前端交流群,汇集了各路大神,期待你的加入!(文末有我wx,或者私我)

@TOC

专栏介绍

TypeScript从入门到实践专栏是博主在学习和工作过程中的总结,实用性非常强,内容会不断进行精进,欢迎订阅哦,学会TS不迷路。

TS系列

标题

基础篇

基础篇

基础篇

基础篇

基础篇

基础篇

==<font color=red >进阶篇</font>==

==<font color=red >进阶篇</font>==

==<font color=red >进阶篇</font>==

TS装饰器(九)

装饰器

装饰器(Decorator)是一种特殊类型的声明,它能够被附加到类声明、方法、属性或参数上,装饰器的本身。其本身是一个函数,会在运行的时候被调用,被装饰的声明信息会作为参数传递给装饰器函数,当作形参。装饰器本质上主要是在操作原型对象,通过给原型对象 prototype添加一些方法和属性,来扩展类的功能。

装饰器主要分为类装饰器(接收1个参数)、属性装饰器(接收2个参数)、方法装饰器(接收3个参数、参数装饰器(接收3个参数),不同装饰器接收参数也不一同。另外TS内置了装饰器类型,我们直接用就好了。

装饰器分类

ts内置装饰器类型

接收参数

类装饰器

ClassDecorator

1个,类函数

方法装饰器

MethodDecorator

3个,类函数,方法名,成员属性描述符

属性装饰器

PropertyDecorator

2个,类函数、属性名称

参数装饰器

ParameterDecorator

3个,类函数,参数名,参数所在位置的索引

要想在 TypeScript中使用装饰器,必须将 tsconfig.jsonexperimentalDecorators设置为true,具体如下所示:

  • 生成tsconfig.json文件
代码语言:javascript
复制
tsc --init
  • 配置
代码语言:javascript
复制
tsc --target ES5 --experimentalDecorators
代码语言:javascript
复制
{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,                   /* Enable experimental support for TC39 stage 2 draft decorators. */
    "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
    }
 }
  • 语法 @expressionexpression是一个函数,位置根据不同类型的装饰器要求放置。

1、类装饰器

(1)一个装饰器

类装饰器接收一个构造函数作为参数,参数的类型是一个函数。

代码语言:javascript
复制
function ClassDecorator(target: Function): void {
  target.prototype.start = function(): void {
      // 通用功能
      console.log('1')
  }
}
@ClassDecorator
class Course {
  constructor() {
      // 业务逻辑
  }
}
let course = new Course();
console.log('course',course.start())

(2)装饰器累加

装饰器不是只能定义一个,可以定义多个作用于一个类函数,通过装饰器累加从而给类追加多个方法和属性,可以用来监视、修改、替换类定义。

  • 参数:只有target一个,意思是类函数本身
代码语言:javascript
复制
function StartTime(target: Function): void {
  target.prototype.start = function(): void {
      // 通用功能
      console.log('start')
  }
}
function EtartTime(target: Function): void {
  target.prototype.end = function(): void {
      // 通用功能
      console.log('end')
  }
}
@StartTime
@EndTime
class Course {
  constructor() {
      // 业务逻辑
  }
}
let course = new Course();
console.log('course',course.start())
console.log('course',course.end())

(3)装饰器传参

装饰器传参,那么怎么接受呢,参数如何放置,只需要在内部再返回一个装饰器就可,参数在外部进行接收,具体例子如下所示:

代码语言:javascript
复制
function ClassDecorator(name: string) {
  return (target: any)  => {
    target.prototype.name = name
  }
}
@ClassDecorator('zhangsan')
class Course {
  constructor() {
      // 业务逻辑
  }
}
let course:p = new Course();
interface p {
   name?:string
}
console.log('course',course.name)//zhangsan

2、方法装饰器

方法装饰器使用与类装饰器基本相同,方法装饰器需要放在类方法的前面,方法作为参数传给方法装饰器,接收三个参数,具体如下:

  • target: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • propertyKey: 方法名称。
  • descriptor: 成员的属性描述符。
代码语言:javascript
复制
//PropertyDescriptor类型是ts内置的
function MethodsDecorator (target: Object, propertyKey: string, descriptor: PropertyDescriptor){
     console.log(target)
     console.log(propertyKey)
     console.log(descriptor)
}

class Person {
    name: string = ''
    age: number = 0

    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    @MethodsDecorator
    getName() {
      return this.name
    }

    @MethodsDecorator
    getAge() {
      return this.age
    }
}

const p = new Person('张三', 18)
p.getName() // getName:张三
p.getAge() // getAge:18
在这里插入图片描述
在这里插入图片描述

我们可以看到打印出来的值,getNamegetAge被一一打印出来以及属性描述符。其中属性描述符主要包括以下四个属性:

  • configurable:是否可删除const propertyName = (target: Object, propertyKey: string) => { console.log(target, propertyKey) } class Person { @propertyName name: string = '' @propertyName age: number = 0 constructor(name: string, age: number) { this.name = name this.age = age } } const p = new Person('张三', 18)打印结果如下所示:
  • enumerable:是否可枚举
  • value:属性值
  • writable:是否可修改3、属性装饰器属性装饰器只接收两个参数,具体如下:
  • target: 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • propertyKey:属性名称
在这里插入图片描述
在这里插入图片描述

注意:如果@propertyName只写在name: string = ''上面,则只会打印出name相关的数据。

4、参数装饰器

参数装饰器用于装饰函数的参数,与方法装饰器一样接收三个参数,具体如下:

  • target:对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。const paramDecorator = (target: any, propertyKey: string, paramIndex: number) => { console.log(target, propertyKey, paramIndex) } class Person { name: string = ''; age: number = 0; constructor(name: string, age: number) { this.name = name; this.age = age; } setName(age:number,@paramDecorator name: string) { this.name = name; this.age = age; } } const p = new Person('张三', 18) p.setName(1,'李四')打印结果如下所示:
    在这里插入图片描述
    在这里插入图片描述
  • propertyKey:属性名称。
  • paramIndex::参数所在位置的索引

5、实际应用

(1)错误信息自定义

怎么使用装饰器进行错误信息自定义,这里使用方法装饰器来对传进来的函数进行处理,主要步骤如下:

  • 解构参数 const ErrorDecorator:MethodDecorator = (...args: any[]) => { const [,,descriptor] = args; const method = descriptor.value descriptor.value = () =>{ try { method() } catch (error) { console.log('这是新定义的错误') } } } class User { @ErrorDecorator public errorMsg () { throw new Error('报错了') } } new User().errorMsg()在使用装饰器时先将原有的值进行存储一下,再去使用,以此来确保它使用的是类中的方法中的值。
  • 取到传进来的函数
  • 使用try...catch执行函数,新的报错定义在catch

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 专栏介绍
  • 装饰器
    • 1、类装饰器
      • (1)一个装饰器
      • (2)装饰器累加
      • (3)装饰器传参
    • 2、方法装饰器
      • 4、参数装饰器
        • 5、实际应用
          • (1)错误信息自定义
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档