Skip to content

方法装饰器

基本语法

ts
/**
 * 参数说明
 * @param target 对于静态方法来说值是类, 对于实例方法来说值是原型对象
 * @param propertyKey 方法的名称
 * @param descriptor 方法的描述对象, 其中 value 属性是被装饰的方法
 */
function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log(target)
  console.log(propertyKey)
  console.log(descriptor)
}

class Person {
  constructor(
    public name: string,
    public age: number
  ) { }
  // 实例方法
  @Demo speak() {
    console.log(`我是${this.name}, 今年${this.age}岁`)
  }
  // 静态方法
  @Demo static isAdult(age: number) {
    return age >= 18
  }
}

const man = new Person('张三', 20)
man.speak()

应用示例

需求:

  • 定义一个Logger方法装饰器, 用于在方法执行前和执行后, 均追加一些额外逻辑
  • 定义一个Validate方法装饰器, 用于验证数据
ts
function Logger(_target: object, propertyKey: string, descriptor: PropertyDescriptor) {
  // 存储原始方法
  const original = descriptor.value
  // 替换原始方法
  descriptor.value = function(...args: any[]) {
    console.log(`${propertyKey}开始执行...`)
    // 执行原函数
    const res = original.call(this, ...args)
    console.log(`${propertyKey}执行完毕...`)
    return res
  }
}

function Validate(maxAge: number) {
  return function(_target: object, _propertyKey: string, descriptor: PropertyDescriptor) {
    // 保存原始方法
    const original = descriptor.value
    // 替换原始方法
    descriptor.value = function(...args: any[]) {
      if (args[0] > maxAge) {
        throw new Error('年龄非法!')
      }
      return original.apply(this, args)
    }
  }
}

class Person {
  constructor(
    public name: string,
    public age: number
  ) { }
  // 实例方法
  @Logger speak() {
    console.log(`我是${this.name}, 今年${this.age}岁`)
  }
  // 静态方法
  @Validate(120) static isAdult(age: number) {
    return age >= 18
  }
}

const man = new Person('张三', 20)
man.speak()