ts

装饰器

// decorator.ts

// **各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器; 如果每种有多个,则从后往前执行**

/**
 * 1.类装饰器, 扩展原型的属性
 */
export function addAge(args: number) {
  return function (target: Function) {
    target.prototype.age = args
  }
}

/**
 * 2.属性装饰器, 修改原有属性的值
 */
export function Property(args: string) {
  return function (target: any, attr: any) {
    target[attr] = args
  }
}

/**
 * 3.1方法装饰器, 在class新增一个方法
 */
export function configurable(params: any) {
  return (
    target: any, //当前装饰的函数容器
    propertyKey: string, //被装饰的函数
    descriptor: PropertyDescriptor //描述属性
  ) => {
    // console.log(target,'target')
    // console.log(propertyKey,'propertyKey')
    // console.log(descriptor.value,'descriptor')
    // descriptor.configurable = params
    target.run = () => {
      console.log('run方法打印:', params)
    }
  }
}

/**
 * 3.2方法装饰器, 修改原有方法
 */
export function parseFunc(params: any) {
  return (
    target: any, //当前装饰的函数容器
    propertyKey: string, //被装饰的函数
    descriptor: PropertyDescriptor //描述属性
  ) => {
    const originalMethod = descriptor.value //保存当前方法
    descriptor.value = function (...args: any[]) {
      args = args.map(value => {
        return String(value)
      })
      console.log(args, 'new args')
      originalMethod.apply(this, args) //没有这句是直接修改, 有这句可以最后执行原来的内容
    }
  }
}

/**
 * 4方法参数装饰器
 */

function Method(params: string) {
  // 参数1 类的构造函数(静态成员)/原型对象(实例成员)  prototype === HttpClient3.prototype
  // 参数2 方法的名字
  // 参数3 方法描述
  return function (prototype: any, name: string, desc: any) {
    // 保存之前的方法
    const oldMethod = desc.value
    desc.value = function (...args: any) {
      args = args.map((item: any) => {
        return String(item)
      })
      console.log('方法装饰器内部 ', args)
      // console.log('method invoke start -----', new Date() - 0)
      oldMethod.apply(this, args)
      // console.log('method invoke end -----', new Date() - 0)
    }
  }
}

/**
 *  省略里面函数的一种思路,暂未实现
 */

//  export function parseFunc(target, name, descriptor) {
//   const originalMethod = descriptor.value
//   descriptor.value = function (...parseConf: any[]) {
//     for (let index = 0; index < parseConf.length; index++) {
//       const type = parseConf[index]
//       console.log(type,'type')
//       switch (type) {
//         case 'number':
//           parseConf[index] = Number(parseConf[index])
//           break
//         case 'string':
//           parseConf[index] = String(parseConf[index])
//           break
//         case 'boolean':
//           parseConf[index] = String(parseConf[index]) === 'true'
//           break
//       }
//       return originalMethod.apply(this, parseConf)
//     }
//   }
//   console.log(descriptor,'descriptor')
//   return descriptor
// }

# 1. 使用

import * as Dor from './decorator'

// @Dor.addAge(17)  //调用类装饰器,不能放到class里面
export default class Example {
  [x: string]: any  //表示 可能被装饰器新增的方法或者属性
  age: number
  @Dor.Property('百度')  //更改属性apiurl的值
  public apiurl: string | undefined
  // constructor() {
  //   this.apiurl = '我是构造函数里面的apiUrl'  //构造函数的值会覆盖属性装饰器里面的
  // }

  // @Dor.configurable('ddddddddddddddd')    //调用方法装饰器 3.1

  @Dor.parseFunc('99999')  //调用方法装饰器 3.2  // 99999这个传参用到则传,不用可以不传
  getData(params: any){
    console.log('我是原来方法的内容')
  }
}
上次更新: