[TypeScript语法7]decorators

/**来源:https://www.tslang.cn/docs/handbook/decorators.html
 * 1,装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。
 * 2,在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:
 *   由上至下依次对装饰器表达式求值。
 *   求值的结果会被当作函数,由下至上依次调用。
 * 3,类中不同声明上的装饰器将按以下规定的顺序应用:
 *   参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个实例成员。
 *   参数装饰器,然后依次是方法装饰器,访问符装饰器,或属性装饰器应用到每个静态成员。
 *   参数装饰器应用到构造函数。
 *   类装饰器应用到类。
 * 4,类装饰器:应用于类构造函数,可以用来监视,修改或替换类定义。
 *   类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数
 * 5,方法装饰器:会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
 *   方法装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
 *     对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
 *     成员的名字。
 *     成员的属性描述符。
 * 6,访问装饰器:一个成员的所有装饰的必须应用在文档顺序的第一个访问器上。
 *     这是因为,在装饰器应用于一个属性描述符时,它联合了get和set访问器,而不是分开声明的。
 *     访问器装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
 *      对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
 *      成员的名字。
 *      成员的属性描述符。*/

//1,装饰器工厂
function color(value: string) {
  return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(value);//5
  }
}

//2,装饰器组合
function f(somObj: Object) {
  console.log(somObj);//1
  return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(descriptor.value.toString());//4,能输出函数的内容
  }
}

function g() {
  console.log("g(): evaluated");//2
  return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(target.method.toString());//3,能输出函数的内容
  }
}

class C {
  @color("yellow")
  @f({name: "hello function decorators"})
  @g()
  method() {
    console.log(Object.keys(this))
  }
}

//3,类装饰器
//{new(...args: any[]): Object} 这个应该是constructor的类型定义
function classDecoratorWithParams(params: Object) {
  return function classDecorator<T extends {new(...args: any[]): Object}>(constructor: T) {
    return class someNewClass extends constructor {//这个写法相当于继承了原始类,但只增加了构造方法
      newProperty = params;
      hello = "override";
    }
  }
}

function enumerable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.enumerable = value;
  }
}

//Configurable:表示能否通过delete删除属性从而重新定义属性;
//只要一旦将configurable设置为false,将不能再调用Object.defineProperty()对属性的行为进行修改
function configurable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.configurable = false;
  };
}

@classDecoratorWithParams({name: "some name"})
class Greeter {
  property = "property";
  hello: string;

  constructor(m: string) {
    this.hello = m;
  }

  @enumerable(false)
  funForTestMethodDecorators() {
    console.log(this.hello)
  }

  @configurable(false)
  get propertyVisitorDecorator() {
    return this.property;
  }

  set propertyVisitorDecorator(value: string) {
    this.property = value;
  }
}
let G20 = new Greeter("world");
/*someNewClass {//改了类名字了,不是Greeter,是someNewClass
 property: 'property',
 hello: 'override',
 newProperty: { name: 'some name' } }*/
delete G20.propertyVisitorDecorator;//加不加configurable装饰器都删不了,不清楚原因啊~
for (let o in G20) {//没有funForTestMethodDecorators方法,删除装饰器就有了.
  console.log(o)
}
//4,方法装饰器,enumerable
//5,访问器装饰器,configurable
//6,属性装饰器和参数装饰器都有些复杂,用的也不多,等用到再说吧。~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值