装饰器

装饰器是一个函数,然后使用@装饰器函数修饰被装饰对象,以达到不修改原始代码实现添加(修改)功能的目的。安装被修饰对象可以分为:

  1. 类装饰器:装饰类构造函数
  2. 属性装饰器:装饰类实例属性
  3. 函数装饰器:装饰类实例函数
  4. 参数装饰器:装饰类实例函数参数

类装饰器

ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction;

类装饰器通过操作类的构造函数,实现对类的属性和方法的修改,类装饰器只接受一个参数target即类本身的构造函数

function decoratorDemo(target) {
  target.isDec = true;
}

@decoratorDemo
class Demo {}
console.log(Demo.idDec); // true

还可以结合高阶函数给装饰器传参

function decoratorDemo(idDec) {
  return function (target) {
    target.isDec = isDec;
  };
}

@decoratorDemo(true)
class Demo {}

console.log(Demo.idDec); // true

函数装饰器

使用函数装饰器可以控制函数的输入输出,函数装饰器在class声明时执行,而不是在实例化时

MethodDecorator = <T>(target: Object, key: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | Void;

函数装饰器接收三个属性:

  • target:被装饰的对象
  • key:被装饰的函数名
  • descriptor:函数的属性描述符,可以通过Object.getOwnPropertyDescriptor()方法查看, 参考对象属性模型

函数装饰器的本质就是通过修改descriptor实现增强(装饰)效果

function InjectPrefix(prefix: string) {
  return function(target, key, descriptor) {
    const originFunc = descriptor.value
    descriptor.value = function(...args) {
      return originFunc(prefix + args[0])
    }
    return descriptor
  }
}

class Demo {
  @InjectPrefix('Mike-')
  log(x) {
    console.log(x)
  }
}

const demo = new Demo()
demo.log('Jordan'); // Mike-Jordan

属性装饰器

属性装饰器和函数装饰器类似,可以重新定义gettersetterenumerableconfigurable等属性和方法。

PropertyDecorator = (target: Object, key: string) => void;

属性装饰器有两个参数:

  • target:属性拥有者,即类的实例
  • key:属性名
class Prop {
  @init(16)
  age: number
}

function init(age: number) {
  return function(target, key) {
    target[key] = age
    return target
  }
}

const prop = new Prop();
console.log(prop.age)

参数装饰器

接收三个属性:

  • target:类实例
  • key:参数名
  • index:参数下标


results matching ""

    No results matching ""