简介:
-
装饰器本质是一种特殊的函数,它可以对:类,函数,方法,参数进行扩展,同时能让代码更简洁。
-
装饰器自2015年在ECMA-script-6中被提出,目前为止仍是实验性特征,需要开发者手动调整配置,来开启装饰器支持
-
装饰器有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属性装饰器,来监视属性的修改
方法装饰器
基本语法
应用举例
需求:
- 定义一个Logger方法装饰器,用于在方法执行前和执行后,均追加一些额外逻辑。
- 定义一个Validate方法装饰器,用于验证数据