当前位置: 首页 > ai >正文

TypeScript装饰器-简洁版

TypeScript 中的装饰器(Decorators)是一种特殊类型的声明,它能够被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 这种形式,其中 expression 必须计算为一个函数,该函数会在运行时被调用。

装饰器的主要用途是修改或增强类、属性、方法或参数的行为。TypeScript 装饰器是实验性功能,需要在 tsconfig.json 文件中启用 experimentalDecorators 选项才能使用。

以下是装饰器的几种常见用法和示例:


1. 类装饰器

类装饰器用于修饰类本身。它接收一个参数,即类的构造函数。

示例:添加日志功能
function Logger(constructor: Function) {console.log("Logging...");console.log(constructor);
}@Logger
class Person {name = "John";constructor() {console.log("Creating person object...");}
}const person = new Person();
console.log(person);

输出:

Logging...
[Function: Person]
Creating person object...
Person { name: 'John' }
示例:修改类的行为
function WithTemplate(template: string, hookId: string) {return function(constructor: any) {const hookEl = document.getElementById(hookId);const p = new constructor();if (hookEl) {hookEl.innerHTML = template;hookEl.querySelector("h1")!.textContent = p.name;}};
}@WithTemplate("<h1>Person Object</h1>", "app")
class Person {name = "John";constructor() {console.log("Creating person object...");}
}

HTML:

<div id="app"></div>

输出:
在页面中显示:

<h1>John</h1>

2. 方法装饰器

方法装饰器用于修饰类中的方法。它接收三个参数:

  1. 对于静态成员,是类的构造函数;对于实例成员,是类的原型对象。
  2. 成员的名称。
  3. 成员的属性描述符。
示例:方法装饰器
function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {console.log(`Logging the call of ${propertyName}`);console.log(args);const result = originalMethod.apply(this, args);console.log(result);return result;};
}class Product {title: string;private _price: number;constructor(t: string, p: number) {this.title = t;this._price = p;}@LoggetPriceWithTax(tax: number) {return this._price * (1 + tax);}
}const product = new Product("Book", 19.99);
console.log(product.getPriceWithTax(0.2));

输出:

Logging the call of getPriceWithTax
[0.2]
23.988
23.988

3. 访问器装饰器

访问器装饰器用于修饰类中的访问器(getter 或 setter)。它接收两个参数:

  1. 对于静态成员,是类的构造函数;对于实例成员,是类的原型对象。
  2. 成员的名称。
示例:访问器装饰器
function Log(target: any, propertyName: string) {console.log("Property decorator!");console.log(target);console.log(propertyName);
}class Product {private _price: number;constructor(p: number) {this._price = p;}@Logget price() {return this._price;}@Logset price(value: number) {this._price = value;}
}const product = new Product(10);
console.log(product.price);
product.price = 20;

输出:

Property decorator!
Product {}
price
Property decorator!
Product {}
price
10

4. 参数装饰器

参数装饰器用于修饰类方法的参数。它接收三个参数:

  1. 对于静态成员,是类的构造函数;对于实例成员,是类的原型对象。
  2. 成员的名称。
  3. 参数的索引。
示例:参数装饰器
function Log(target: any, propertyName: string, index: number) {console.log("Parameter decorator!");console.log(target);console.log(propertyName);console.log(index);
}class Product {title: string;private _price: number;constructor(t: string, p: number) {this.title = t;this._price = p;}getPriceWithTax(@Log tax: number) {return this._price * (1 + tax);}
}const product = new Product("Book", 19.99);
console.log(product.getPriceWithTax(0.2));

输出:

Parameter decorator!
Product {}
getPriceWithTax
0
23.988

5. 组合使用装饰器

装饰器可以组合使用,但需要注意执行顺序:

  • 参数装饰器先执行。
  • 方法装饰器次之。
  • 访问器装饰器再次。
  • 最后是类装饰器。
示例:组合装饰器
function ClassDecorator(constructor: Function) {console.log("Class decorator");
}function MethodDecorator(target: any, propertyName: string, descriptor: PropertyDescriptor) {console.log("Method decorator");
}function ParameterDecorator(target: any, propertyName: string, index: number) {console.log("Parameter decorator");
}@ClassDecorator
class Product {constructor() {}@MethodDecoratormethod(@ParameterDecorator param: string) {}
}

输出:

Parameter decorator
Method decorator
Class decorator

6. 装饰器工厂

装饰器工厂是一个返回装饰器的函数,可以接收参数。

示例:装饰器工厂
function Log(prefix: string) {return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {console.log(`${prefix}: Logging the call of ${propertyName}`);console.log(args);const result = originalMethod.apply(this, args);console.log(result);return result;};};
}class Product {title: string;private _price: number;constructor(t: string, p: number) {this.title = t;this._price = p;}@Log("PRODUCT")getPriceWithTax(tax: number) {return this._price * (1 + tax);}
}const product = new Product("Book", 19.99);
console.log(product.getPriceWithTax(0.2));

输出:

PRODUCT: Logging the call of getPriceWithTax
[0.2]
23.988
23.988

7. 装饰器的限制

  • 装饰器是实验性功能,需要在 tsconfig.json 中启用 experimentalDecorators
  • 装饰器的执行顺序需要注意,参数装饰器先执行,方法装饰器次之,访问器装饰器再次,最后是类装饰器。
  • 装饰器不能直接修改类的构造函数或方法的返回值,需要通过返回一个新的构造函数或方法来实现。

总结

装饰器是 TypeScript 中一个非常强大的功能,可以用来增强类、方法、属性和参数的行为。通过合理使用装饰器,可以实现诸如日志记录、权限检查、性能监控等功能,而无需修改原始代码。

http://www.xdnf.cn/news/6151.html

相关文章:

  • 启动窗体自动输入上次内容——CAD c#二次开发
  • MySQL--day1--数据库概述
  • [20250514] 脑机接口行业调研报告(2024年最新版)
  • Sunsetting 创建 React App
  • 斜率变化策略
  • 手写CString类
  • UniApp Vue3事件适配与兼容方案
  • python 练习 五
  • IIS服务器URL重写配置完整教程
  • MySQL视图:虚拟表的强大功能与应用实践
  • 国产化环境下的 DICOM 网络服务与影像处理适配
  • Yolov8的详解与实战-深度学习目标检测
  • 关于vue学习的经常性错误
  • KUKA库卡焊接机器人智能气阀
  • 亚远景-对ASPICE评估体系的深入研究与分析
  • ConfigMap 和 Secret 是否支持热更新
  • 系统单元测试和项目打包
  • Jmeter -- JDBC驱动连接数据库超详细指南
  • 东莞文件服务器存储维修-DELL MD3400电池故障
  • C++学习细节回顾(汇总二)
  • 基于Spring AI与Hugging Face TGI构建高效聊天应用:从配置到实践全解析
  • centos中postfix的作用
  • 用git下载vcpkg时出现Connection was reset时的处理
  • SpringBoot集成Kafka
  • Python × CARLA:如何在自动驾驶仿真世界里打造智能驾驶系统?
  • ansible进阶02
  • vivado原语
  • AI编程:使用Trae + Claude生成原型图,提示词分享
  • 一次因校时服务器异常引起的性能差异分析
  • 浏览器相关