Skip to content

访问器装饰器

基本语法

ts
/**
 * 参数说明
 * @param target 对于实例访问器来说值是[所属类的原型对象], 对于静态访问器来说值是[所属类]
 * @param propertyKey 访问器的名称
 * @param descriptor 描述对象
 */
function Demo(target: object, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log(target)
  console.log(propertyKey)
  console.log(descriptor)
}

class Person {
  @Demo
  get address() {
    return '北京'
  }
  @Demo
  static get country() {
    return '中国'
  }
}

应用示例

需求: 对Weather类的temp属性的set访问器进行限制, 设置最低温度为-50, 最高温度为50

ts
function RangeValidate(min: number, max: number) {
  return function(target: object, propertyKey: string, descriptor: PropertyDescriptor) {
    // 保存原始的 setter 方法, 以便在后续调用中使用
    const originalSetter = descriptor.set
    // 重写 setter 方法, 加入温度范围验证逻辑
    descriptor.set = function (v: number) {
      // 检查设置的值是否在指定的最小值和最大值之间
      if (v < min || v > max) {
        throw new Error(`${propertyKey}的值应该在${min} - ${max}之间!`)
      }

      // 如果值在范围内, 且原始的 setter 方法存在, 则调用原始的 setter 方法
      if (originalSetter) {
        originalSetter.call(this, v)
      }
    }
  }
}

class Weather {
  private _temp: number
  constructor(temp: number) {
    this._temp = temp
  }

  @RangeValidate(-50, 50)
  set temp(v) {
    this._temp = v
  }
  get temp() {
    return this._temp
  }
}

const w = new Weather(25);
console.log(w)
w.temp = 70
console.log(w)