TS装饰器基础使用

85 阅读3分钟

简介:

  1. 装饰器本质是一种特殊的函数,它可以对:类,函数,方法,参数进行扩展,同时能让代码更简洁。

  2. 装饰器自2015年在ECMA-script-6中被提出,目前为止仍是实验性特征,需要开发者手动调整配置,来开启装饰器支持

  3. 装饰器有5种:

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

虽然TyoeScript5.0中可以直接使用类装饰器,但为了确保其他装饰器可用,现阶段使用时,仍建议使用experimentalDecorators配置来开启装饰器支持,而且不排除在未来版本中,官方会进一步调整装饰器的相关语法

类装饰器

基本语法

类装饰器是一个应用在类声明上的函数,可以为类添加额外的功能,或添加额外的逻辑

应用举例

需求:定义一个装饰器,实现Person实例调用toString时返回JSON.stringify的执行结果

关于返回值

类装饰器有返回值:若类装饰器返回一个新的类,那这个新的类将替换掉被被装饰的类。

类装饰器无返回值:若类装饰器无返回值或返回undefined,那被装饰的类不会被替换。

关于构造类型

在TS中,Function类型所表示的范围十分广泛,包括:普通函数,箭头函数,方法等。

但并非Function类型的函数都可以被new关键字实例化,例如箭头函数不能被实例化。

在TS中声明一个构造类型,有以下两种方式:

替换被装饰的类

对于高级一些的装饰器,不仅仅是覆盖一个原型上的方法,还要有更多功能,例如添加新的方法和状态。

需求:设计一个LogTime装饰器,可以给实例添加一个树形,用于记录实例对象的创建时间,再添加一个方法用于读取创建时间

//自定义类型class
type Constructer = new (...args:any[]) => {}
//定义接口
interface Person {
    getTime():void
}
//装饰器
function LogTime<T extends Constructer>(target:T) {
    return class extends target {
    createdTime:Date
    constructer(...args:any[]){
        super(...args)
        this.createdTime = new Date()
    }
    getTime(){
        return `该对象的创建时间是:${this.createdTime}`
        }
    }
}
//被装饰的类
@LogTime
calss Person {
    name:string
    age:number
    constructer(name:string,age:number){
        this.name = name
        this.age = age
    }
    speak(){
        condole.log('你好!')
    }
}

const p1 = new Person('张三'20)
console.log(p1.setTime())

装饰器工厂

装饰器工厂是一个返回装饰器函数的函数,可以为装饰器添加参数,可以更灵活的控制装饰器的行为

需求:定义一个LogInfo类装饰器工厂,实现Person实例可以调用到introduce方法,且introduce中输出内容的次数,由LogInfo接收的参数决定。

装饰器组合

装饰器可以组合使用,执行顺序为:先【由上到下】的执行所有的装饰器工厂,依次获取到装饰器,然后再【由下到上】执行所有装饰器

执行结果:

属性装饰器

基本语法

属性遮蔽

如下代码中:当构造其中的this..age = age 试图在实例上赋值时,实际上是调用了原型上age属性的set方法

应用举例

需求:定义一个State属性装饰器,来监视属性的修改

方法装饰器

基本语法

应用举例

需求:

  1. 定义一个Logger方法装饰器,用于在方法执行前和执行后,均追加一些额外逻辑。
  2. 定义一个Validate方法装饰器,用于验证数据

访问器装饰器

基本语法

应用举例

参数装饰器

基本语法