装饰器组合
装饰器可以组合使用
执行顺序
执行顺序为: 先由上到下的执行所有的装饰器工厂, 依次获取到装饰器, 然后再由下到上执行所有的装饰器
ts
// 装饰器
function DemoA(target: Function) {
console.log('DemoA')
}
// 装饰器工厂
function DemoB() {
console.log('DemoB 工厂')
return function (target: Function) {
console.log('DemoB')
}
}
// 装饰器工厂
function DemoC() {
console.log('DemoC 工厂')
return function (target: Function) {
console.log('DemoC')
}
}
// 装饰器工厂
function DemoD(target: Function) {
console.log('DemoD')
}
@DemoA
@DemoB()
@DemoC()
@DemoD
class Person {}
/**
* 执行顺序:
* 1. DemoB 工厂
* 2. DemoC 工厂
*
* 3. DemoD
* 4. DemoC
* 5. DemoB
* 6. DemoA
*/
应用示例
ts
interface Person {
introduce: () => void
getTime: () => string
}
type Constructor = new (...args: any[]) => {}
// 装饰器
function CustomString(target: Constructor) {
target.prototype.toString = function() {
return JSON.stringify(this)
}
// 封锁 target 的原型链属性
Object.seal(target.prototype)
}
// 装饰器工厂
function LogInfo(n: number) {
// 返回的是装饰器
return function (target: Constructor) {
target.prototype.introduce = function() {
for (let i = 0; i < n; i++) {
console.log(`我是${this.name}, 今年${this.age}岁`)
}
}
}
}
// 装饰器
function LogTime<T extends Constructor>(target: T) {
return class extends target {
createTime: Date;
constructor(...args: any[]) {
super(...args)
this.createTime = new Date()
}
getTime() {
return `该对象创建时间为: ${this.createTime}`
}
}
}
@CustomString
@LogInfo(3)
@LogTime
class Person {
constructor(
public name: string,
public age: number
) {}
speak() {
console.log('Halo')
}
}
const man = new Person('张三', 18)
man.speak()
console.log(man.toString())
man.introduce()
console.log(man.getTime())