VVLL.net

Decorators(装饰器)

日期:2024-08-22 09:58:31

TypeScript 中的装饰器(Decorators)是一种实验性特性,它可以用来添加元数据和修改类及其成员的行为。装饰器是一种函数,可以附着在类声明、方法、访问器、属性或参数上,并在运行时通过 @decorator 语法应用于相应的声明或表达式上。

1. 基本概念

装饰器允许开发者通过注释或修饰类的方式来声明一些特性,这些特性包括:

  • 类装饰器:应用于类的声明之前,可以用来修改类的行为。
  • 方法装饰器:应用于方法的声明之前,可以用来修改方法的行为。
  • 访问器装饰器:应用于访问器(getter 和 setter)的声明之前,可以用来修改访问器的行为。
  • 属性装饰器:应用于属性的声明之前,可以用来修改属性的行为。
  • 参数装饰器:应用于函数参数的声明之前,可以用来修改参数的行为。

2. 使用装饰器的语法

装饰器是一个函数,它接收三个参数:

  • 对于类成员(方法、属性、访问器或参数),装饰器的参数如下:
    • 对于静态成员,是类的构造函数。
    • 对于实例成员,是类的原型对象。
    • 对于方法、访问器和属性,是成员的名称。
    • 对于参数,是参数的索引。

装饰器函数的实现可以是任何有效的 JavaScript 函数,通常返回一个函数或者直接操作传入的参数。

3. 示例

3.1 类装饰器示例

// 类装饰器示例
function Logger(target: Function) {
  console.log('Logger invoked on', target);
}

@Logger
class MyClass {
  constructor(private name: string) {}

  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}

const myInstance = new MyClass('Alice');
myInstance.greet(); // 输出:Hello, Alice!

3.2 方法装饰器示例

// 方法装饰器示例
function Log(target: any, key: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`Calling method ${key} with args: ${JSON.stringify(args)}`);
    return originalMethod.apply(this, args);
  };
  return descriptor;
}

class Calculator {
  @Log
  add(x: number, y: number): number {
    return x + y;
  }
}

const calculator = new Calculator();
console.log(calculator.add(2, 3)); // 输出:Calling method add with args: [2,3],5

4. TypeScript 中的装饰器限制和注意事项

  • 实验性特性:装饰器目前仍处于实验阶段,可能会有语法和行为上的变化。
  • 装饰器顺序:多个装饰器的执行顺序是从下到上、从右到左的。
  • 装饰器应用目标:不同类型的装饰器只能应用于特定类型的声明(例如方法装饰器只能应用于方法)。
  • 编译选项:使用装饰器需要将 TypeScript 编译器的 experimentalDecorators 选项设置为 true

5. 总结

装饰器是 TypeScript 中一个强大的特性,它使得可以通过简单的语法来修改类及其成员的行为,例如添加日志、验证等功能。虽然装饰器目前还是一个实验性特性,但在某些场景下可以提供非常有用的功能增强。在使用装饰器时,建议始终关注 TypeScript 和 JavaScript 的最新文档和规范,以确保正确和稳定的使用。

参考

标签