Skip to content

装饰器用于扩展类的属性和方法

ts
// 扩展类的方法
function PersonDesc (target: Function) { // target 是类
  target.prototype.sayHello = () => {
    console.log('Hello')
  }
}

// 扩展类的属性
function nameDesc (target: any, key: string) { // target 是类的原型
  let value = target[key]

  Object.defineProperty(target, key, {
    get () {
      return value.toUpperCase()
    },

    set (newValue) {
      value = newValue
    }
  })
}

// 扩展类的静态属性
function ageDesc (target: any, key: string) { // target 是类
  let value = target[key]

  Object.defineProperty(target, key, {
    get () {
      return value * 2
    }

    // 修饰类的 static 属性时赋值不走 set
  })
}

// 扩展类的方法
function getNameDesc (target: any, key: string, descriptor: PropertyDescriptor) {
  // target 是类的原型
  // 不可枚举
  descriptor.enumerable = false
}

// 修饰参数
function fnParamDesc (target: any, key: string, index: number) {
  // target 是类的原型
}

@PersonDesc
class Person {
  @nameDesc
  name: string = 'foo'
  sayHello!: Function
  @ageDesc
  static age: number = 18

  @getNameDesc
  getName (@fnParamDesc fnParam: string) {}
}

const p = new Person()
p.sayHello()
p.name // output: 'FOO'
p.name = 'bar'
p.name // output: 'BAR'