1. 装饰器是一种特殊类型的声明,本质上就是一个方法,可以注入到类、方法、属性、参数上,扩展其功能;
  2. 常见的装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器…
  3. 装饰器在写法上有:普通装饰器(无法传参)、装饰器工厂(可传参)
  4. 装饰器已是ES7的标准特性之一


类装饰器

  1. function hello(params: any) {
  2. console.log(params);// 就是World类,可以扩展属性及方法
  3. params.prototype.name = 'world'; // 添加属性
  4. params.prototype.tell = () => { // 添加方法
  5. console.log(`hello ${this.name}`);
  6. }
  7. }
  8. @hello
  9. class World {
  10. // ...
  11. }
  12. const hw:any = new World();
  13. console.log(hw.name); // world
  14. hw.tell() / hello world

上面的hello就被调用了, 它有什么用? 他可以动态扩展 World 类的属性和方法,在不修改类的前提下来扩展。

装饰器工厂

  1. function color(value: string) { // 装饰器工厂 参数是传进来的参数
  2. return function (target) { // 装饰器 参数是类
  3. target.prototype.color = value;
  4. }
  5. }
  6. @color('red')
  7. class Cloth {
  8. // ...
  9. }
  10. const clothany = new Cloth();
  11. console.log(cloth.color); // red

装饰器工厂用的是非常多的,因为他可以传参。

重载构造函数

  1. function color<T extends { new (...args: any[]): {} }>(constructor: T) {
  2. return class extends constructor {
  3. color = "red";
  4. newColor = "green";
  5. getColor() {
  6. console.log(this.newColor);
  7. }
  8. };
  9. }
  10. @color
  11. class Cloth {
  12. color: string;
  13. constructor() {
  14. this.color = "blue";
  15. }
  16. getColor() {
  17. console.log(this.color);
  18. }
  19. }
  20. const cloth: Cloth = new Cloth();
  21. cloth.getColor(); // red
  22. console.log(new Cloth()); // {color: red, newColor: green}

方法装饰器

  1. function enumerable(value: boolean) {
  2. return function (
  3. target: any,
  4. propertyKey: string,
  5. descriptor: PropertyDescriptor
  6. ) {
  7. descriptor.enumerable = value;
  8. console.log(target, propertyKey, descriptor);
  9. // 类, 方法名 属性描述符
  10. };
  11. }
  12. class Greeter {
  13. greeting: string;
  14. constructor(message: string) {
  15. this.greeting = message;
  16. }
  17. @enumerable(false)
  18. greet() {
  19. return "Hello, " + this.greeting;
  20. }
  21. }

当装饰器被执行时, greet的属性描述符的 enumerable 属性 就被设置成了 false

访问器装饰器

  1. function configurable(value: boolean) {
  2. return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  3. descriptor.configurable = value;
  4. };
  5. }
  6. class Point {
  7. private _x: number;
  8. private _y: number;
  9. constructor(x: number, y: number) {
  10. this._x = x;
  11. this._y = y;
  12. }
  13. @configurable(false)
  14. get x() { return this._x; }
  15. @configurable(false)
  16. get y() { return this._y; }
  17. }

成员的属性描述符,可配置项就被修改了。