三、Typescript细节:装饰器
装饰器(Decorator)就是一个特别声明的函数,其可以附加在对象、方法、属性、参数上。这是一个新的设计模式,用装饰器改变行为, 是编译时发生的,而不是在运行时。
作用:可以动态地修改对象、方法、属性、参数的行为,或添加一些额外的任务。
装饰器是先通过函数声明的方式进行声明,之后可用 @ 符号进行修饰,从而达到目的。Typescript中提供了5中不同类型的装饰器:
- 类装饰器:ClassDecorator
- 类方法装饰器:MethodDecorator
- 参数装饰器:ParameterDecorator
- 访问器装饰器:AccessorDecorator
- 类属性装饰器:PropertyDecorator
类装饰器:ClassDecorator
类装饰器会自动将类的构造函数传入target参数中,之后可通过prototype进行设置。类装饰器可在不破坏原有类的情况下,添加一些类原本不存在的属性。
const dec = (target:any) => { target.prototype.name = '小白鲨' } //target = [class A]
@dec
class A {
constructor() {}
}
console.log(new A().name) // 小白鲨
类方法装饰器:MethodDecorator
方法装饰器与属性差不多,不过多了一个参数:原型对象、方法的名称、属性描述符(writable可写、enumerable可枚举、configurable可配置)。
const dec: MethodDecorator = (target:any, key:string|symbol, descriptor:any) => {
console.log(target, key, descriptor)
// 输出:{} getName { value: [Function: getName],
// writable: true,
// enumerable: false,
// configurable: true }
}
class A {
constructor() {}
@dec
getName() {}
}
类属性装饰器:PropertyDecorator
类属性装饰器会返回2个参数:原型对象、属性名称。因此可以对这两个值进行对应的操作。
const dec: PropertyDecorator = (target:any, key:string|symbol) => {
// target = {} 也就是A的原型对象, key = name
console.log(target, key) // 输出:{} name
}
class A {
@dec
public name: string
constructor() { this.name = '' }
}
装饰器工厂
装饰器会默认自带一些参数,因此,如果需要进行像函数一样传参,则需要用到装饰器工程。
接下来就通过装饰器工程、axios实现ajax通讯:
import axios from 'axios'
const Get = (url: string): MethodDecorator => {
return (target, key, descriptor: PropertyDescriptor) => {
let getData = descriptor.value
axios.get(url)
.then(res => { getData (res, { status: 200 }) })
.catch(e => { getData (e, { status: 500 }) })
}
}
class Controller {
constructor() {}
@Get('https://localhost:8080/api/get')
getData (res: any, status: any) {
console.log(res.data.result.list, status)
}
}