走进TypeScript之装饰器

初识

什么是装饰器?

在一些场景下我们需要额外的特性来支持标注或修改类及其成员。我们使用装饰器来实现。

装饰器是一种设计模式,可以动态的实现对类属性的修改,而不需要重载,实现了最大的灵活性。

ts中装饰器怎样实现?

首先运行时开启:

tsc yourDecorator.ts --target ES5 --experimentalDecorators

或者使用配置方式:

tsconfig.json

{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}

ts中装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。


一个简单的示例(装饰器只在解释执行时应用一次。即使没有使用C类,也会打印"hello world"):

// example1
function helloWorld(target: any) {
  console.log("hello world");
}

@helloWorld
class C {
  constructor() {
    console.log("this is constructor");
  }
}


// 结果
// hello world


// example2
function hello(name: string): any {
  return function () {
    console.log("hello,", name);
  };
}

@hello("Pig")
class Pig {
  constructor() {
    console.log("this is the Pig constructor");
  }
}

// 结果
// hello pig

五种装饰器

  1. 类装饰器
  2. 属性装饰器
  3. 方法装饰器
  4. 访问器装饰器
  5. 参数装饰器
// 类装饰器
@classDecorator
class Bird {

  // 属性装饰器
  @propertyDecorator
  name: string;
  
  // 方法装饰器
  @methodDecorator
  fly(
    // 参数装饰器
    @parameterDecorator
      meters: number
  ) {}
  
  // 访问器装饰器
  @accessorDecorator
  get egg() {}
}

 执行顺序

        1. 实例成员

                1.1实例成员参数装饰器

                1.2实例成员方法、访问器、属性装饰器

        2. 静态成员

                1.1静态成员参数装饰器

                1.2静态成员方法、访问器、属性装饰器

        3. 构造器参数装饰器

        4. 类装饰器

function f(key: string): any {
  console.log("evaluate: ", key);
  return function () {
    console.log("call: ", key);
  };
}

@f("Class Decorator")
class C {
  @f("Instance Property")
  prop?: number;
  @f("Static Property")
  static prop?: number;

  @f("Static Method")
  static method(@f("Static Method Parameter") foo) {}

  constructor(@f("Constructor Parameter") foo) {}

  @f("Instance Method")
  method(@f("Instance Method Parameter") foo) {}
}

结果如下:

evaluate:  Instance Property
call:  Instance Property
evaluate:  Instance Method
evaluate:  Instance Method Parameter
call:  Instance Method Parameter
call:  Instance Method
evaluate:  Static Property
call:  Static Property
evaluate:  Static Method
evaluate:  Static Method Parameter
call:  Static Method Parameter
call:  Static Method
evaluate:  Class Decorator
evaluate:  Constructor Parameter
call:  Constructor Parameter
call:  Class Decorator

 注意点:

1. 装饰器执行顺序是后进先出

        1.1 多参数情况,最后一个参数的装饰器会最先被执行

        1.2 装饰器工厂:它返回一个表达式,以供装饰器在运行时调用,多个装饰器工厂,最后一个装饰器返回表达式最先执行。

        1.3 装饰器工厂外部的代码是按照顺序执行,并不是后进先出。

function f(key: string) {
  console.log("evaluate: ", key);
  return function () {
    console.log("call: ", key);
  };
}

class C {
  @f("Outer Method")
  @f("Inner Method")
  method() {}
}

输出:

evaluate: Outer Method
evaluate: Inner Method
call: Inner Method
call: Outer Method

2. 因为ts的类设计原则中,构造器相当于这个类,所以构造器没有所谓的方法装饰器,构造器的 "方法装饰器" 其实就是类装饰器。

五种装饰器具体实现

看下面的博文~~👇🏻

推荐博文

 装饰器 · TypeScript中文网 · TypeScript——JavaScript的超集

TypeScript装饰器,一篇就够了_SuperBin的博客-CSDN博客_typescript 装饰器

https://segmentfault.com/a/1190000022415199

TypeScript装饰器完全指南 | Disenchanted

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值