装饰器学习

LoggerTest

import { LoggerClass, LoggerMethod, LoggerParams, LoggerProperty } from './LoggerDescriptor'

@LoggerClass
class LoggerTest {
  @LoggerProperty
  private readonly info: string

  constructor (private readonly key: string) {
    this.info = 'test'
  }

  @LoggerMethod
  public getLoggerInfo () {
    console.log(this.info, this.key)
  }

  public setLoggerInfo (@LoggerParams key: string) {
    console.log(key)
  }
  private maxValue () {

  }
}


const loggerTest = new LoggerTest('key')
loggerTest.getLoggerInfo()
loggerTest.setLoggerInfo('info')

注解&装饰器

类装饰器

介绍:装饰器是指接受一个类构造函数作为参数的函数,并且返回undefined、参数中提供的构造函数或一个新的构造函数。返回undefined 等同于返回参数中提供的构造函数

const LoggerClass = function (target: any) {}


export const LoggerClass = function (target: any) {
  const original = target
  function construct (constructor: any, args: any) {
    let innerConstruct: any = function () {
      return constructor.apply(original, args)
    }
    innerConstruct.prototype = constructor.prototype
    return new innerConstruct()
  }

  let proxy: any = function(...args: any[]){
    return construct(original, args)
  }
  proxy.prototype = original.prototype
  return proxy
}

方法装饰器

介绍:方法装饰器函数是一个接受三个参数的函数。

  1. 这个属性的对象
  2. 属性名 方法名
  3. 一个可选参数,属性的描述对象
    export const LoggerMethod = function (target: any, key: string, descriptor: any) {}
export const LoggerMethod = function (target: any, key: string, descriptor: any) {
  const originMethod = descriptor.value
  descriptor.value = function (...args: any[]) {
    const result = originMethod.apply(this, args)
    console.log('result', key, args, result)
    return result
  }
}

属性装饰器

介绍:方法装饰器函数是一个接受三个参数的函数。

  1. 这个属性的对象
  2. 属性名 方法名

不需要返回一个属性描述对象
export const LoggerProperty = function (target: any, key: string) {}


export const LoggerProperty = function (target: any, key: string) {
  let original = target[key]
  const getter = () => {
    return original
  }
  const setter = (newval: string) => {
    original = newval
  }
  if(delete target[key]){
    Object.defineProperty(target, key, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true
    })
  }
}

参数装饰器

介绍:方法装饰器函数是一个接受三个参数的函数。

  1. 这个属性的对象
  2. 属性名 方法名
  3. 参数在参数列表中的索引位置

这个装饰器的返回值会被忽略
export const LoggerProperty = function (target: any, key: string) {}

export const LoggerParams = function (target: any, key: string, index: number) {
  const originMethod = target[key]
  target[key] = function (...args: any[]) {
    console.log(args[index])
    originMethod.apply(this, args)
  }
}

完整示例


export const LoggerClass = function (target: any) {
  const original = target
  function construct (constructor: any, args: any) {
    let innerConstruct: any = function () {
      return constructor.apply(original, args)
    }
    innerConstruct.prototype = constructor.prototype
    return new innerConstruct()
  }

  let proxy: any = function(...args: any[]){
    return construct(original, args)
  }
  proxy.prototype = original.prototype
  return proxy
}

export const LoggerMethod = function (target: any, key: string, descriptor: any) {
  const originMethod = descriptor.value
  descriptor.value = function (...args: any[]) {
    const result = originMethod.apply(this, args)
    console.log('result', key, args, result)
    return result
  }
}

export const LoggerProperty = function (target: any, key: string) {
  let original = target[key]
  const getter = () => {
    return original
  }
  const setter = (newval: string) => {
    original = newval
  }
  if(delete target[key]){
    Object.defineProperty(target, key, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true
    })
  }
}

export const LoggerParams = function (target: any, key: string, index: number) {
  const originMethod = target[key]
  target[key] = function (...args: any[]) {
    console.log(args[index])
    originMethod.apply(this, args)
  }
}

export const LoggerAny = function (...args: any[]) {
  const that = args[0]
  switch (args.length) {
    case 1:
      return LoggerClass.call(that, args[0])
    case 2:
      LoggerProperty.call(that, args[0], args[1])
      break
    case 3:
      if (typeof args[2] === 'number') {
        LoggerParams.call(that, args[0], args[1], args[2])
      } else {
        LoggerMethod.call(that, args[0], args[1], args[2])
      }
      break
    default:
      throw new Error('Descriptors are not valid here!')
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从未、淡定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值