2021年2月19日(装饰器)


装饰器

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上。装饰器函数的第一个参数,就是所要装饰的目标类。ES7 中的 decorator其实是一个语法糖, 依赖于 ES5 的 Object.defineProperty 方法

装饰器组合

多个装饰器可以同时应用到被装饰对象上,例如:

@sealed
@test('test')
class Demo {
}

装饰器执行顺序:

  1. 装饰器工厂需要先求值,再装饰,求值顺序是由上到下
  2. 装饰器可以直接求值,装饰顺序是由下到上(在__decorate函数中,通过遍历装饰器列表进行执行,由于遍历的时候是倒序遍历的)

例子如下:

function f() {
    console.log('f求值');
    return function(target: any) {
    	console.log('f装饰');
    }
}
function g() {
    console.log('g求值');
    return function(target: any) {
    	console.log('g装饰');
	}
}
@f()
@g()
class Demo {
}

执行顺序为

f求值
g求值
g装饰
f装饰

装饰器类型

  1. 类装饰器
  2. 方法装饰器
  3. 属性装饰器
  4. 函数参数装饰器
类装饰器

类装饰器在定义类的地方。类装饰器可以监视、修改或替换类定义。类的构造函数将作为唯一参数传递给装饰器。如果类装饰器返回一个值,它会使用返回的构造函数替换原来的类声明。

//类装饰器
function logClass1(params:any) {
  return function(target:any) {
    console.log(target) //当前类
    console.log(params) // 调用装饰器传入实参
  }
}
@logClass1('fsdf')
class HttpClict1 {}
方法装饰器

方法装饰器用来装饰类的方法(静态方法和实例方法都可以)。方法装饰器可以监视、修改或替换方法定义。

方法装饰器接收3个参数:

  • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象

  • 成员的名字

  • 成员属性的描述符

/**
* 方法装饰器会在运行时传入三个参数
* 1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
* 2.成员的名字
* 3.成员属性的描述符
*/
function logMethod(params:any) {
  return function(target:any,methodName:any,desc:any) {
    console.log(target)
    console.log(methodName)
    console.log(desc)
  }
}
class HttpClict1 {
  @logMethod('123')
    getdata(param:any) {

  }
}
属性装饰器
//属性装饰器
function attr(params:any) {
  return function(target:any,attr:any){
    console.log(params) // 属性url传入的形参
    console.log(target) // 当前类
    console.log(attr) //当前属性名称
    target[attr] = params; // 修改构造函数里面的属性
  }
}

class HttpClict1 {
  @attr('12')
  url:string | undefined
}
函数参数装饰器
//方法参数装饰器
/**
* 1.对于静态成员来说是类的构造函数,对于实例成员来说是类的原型对象
* 2.参数 的名字
* 3.参数在函数参数列表中的索引
*/
function logParams(params:string) {
  return function(target:any,methodName:any,paramsIndes:any) {
    console.log(target)
    console.log(methodName)
    console.log(paramsIndes)
	}
}

class HttpClict1 {
  getdata(@logParams('12') param:any) {

  }
}

Author: wxy
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source wxy !
  TOC