【TS入门笔记4---装饰器】
TS入门笔记4
- TypeScript---装饰器
- 一、装饰器基础
- 1. 定义与作用:装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问符、属性或参数上,用来修改类的行为。在 TypeScript 里,装饰器本质上是一个函数,它接收不同的参数并返回一个新的类、方法、属性等。要使用装饰器,需要在tsconfig.json里开启experimentalDecorators选项。
- 2. 配置与启用
- 二、装饰器分类
- 1. 类装饰器:作用对象是类的构造函数。扩展类属性、替换类定义或添加元数据。
- 2. 方法装饰器
- 3. 属性装饰器
- 4. 参数装饰器
- 三、高级技巧
- 1. 装饰器工厂:通过闭包传递参数,生成定制化装饰器
- 3. 元编程与依赖注入
- 四、总结:
- 1.装饰器的执行顺序
- 2.装饰器的应用场景
TypeScript—装饰器
一、装饰器基础
1. 定义与作用:装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、访问符、属性或参数上,用来修改类的行为。在 TypeScript 里,装饰器本质上是一个函数,它接收不同的参数并返回一个新的类、方法、属性等。要使用装饰器,需要在tsconfig.json里开启experimentalDecorators选项。
(1)本质:装饰器是一种特殊声明,通过 @expression 语法附加到类、方法、属性或参数上,用于动态扩展或修改代码行为,属于元编程技术。
(2)核心作用:
扩展功能:无需修改原始代码,动态添加日志、验证、缓存等功能。
元数据管理:标记依赖注入、路由路径等元信息
2. 配置与启用
实验性特性:需在 tsconfig.json 中启用 experimentalDecorators 选项:
{"compilerOptions": {"experimentalDecorators": true}
}
二、装饰器分类
1. 类装饰器:作用对象是类的构造函数。扩展类属性、替换类定义或添加元数据。
(1)禁止修改 Report 类的构造函数和原型
function Sealed(constructor: Function) {Object.seal(constructor);Object.seal(constructor.prototype);
}@Sealed
class Report {title: string;constructor(t: string) { this.title = t; }
}
2. 方法装饰器
参数:target(原型)、propertyKey(方法名)、descriptor(方法描述符)。
应用:添加日志、权限控制或缓存逻辑。
(1)缓存 fibonacci 方法结果以提升性能
function Cache(target: any, methodName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;const cache = new Map();descriptor.value = function (...args: any[]) {const key = JSON.stringify(args);return cache.get(key) || (cache.set(key, originalMethod.apply(this, args)), cache.get(key);};
}class MathService {@Cachefibonacci(n: number): number { /* 计算逻辑 */ }
}
3. 属性装饰器
参数:target(原型)、propertyKey(属性名)。
应用:验证属性值或添加元数据。
(1)自动将 name 属性值转为大写
function Format(target: any, propertyKey: string) {let value = target[propertyKey];Object.defineProperty(target, propertyKey, {set: (newVal) => { value = newVal.toUpperCase(); },get: () => value});
}class User {@Formatname: string;
}
4. 参数装饰器
参数:target(原型)、methodName(方法名)、parameterIndex(参数位置)。
应用:记录参数信息或实现依赖注入。
(1)标记方法参数的元数据
function LogParameter(target: any, methodName: string, index: number) {console.log(`参数 ${index} 在方法 ${methodName} 中被标记`);
}class Service {getUser(@LogParameter id: string) { /* 逻辑 */ }
}
三、高级技巧
1. 装饰器工厂:通过闭包传递参数,生成定制化装饰器
(1)动态配置路由路径:
function Route(path: string) {return function (target: any, methodName: string, descriptor: PropertyDescriptor) {// 将路径与方法关联MetadataStorage.registerRoute(path, target.constructor, methodName);};
}class Controller {@Route('/users')getUsers() { /* 逻辑 */ }
}
(2)装饰器组合
执行顺序:
装饰器表达式:从上到下评估(工厂函数执行)。
装饰器函数:从下到上调用(装饰逻辑执行)。
输出顺序:Second 工厂 → First 工厂 → First 装饰器 → Second 装饰器
@First()
@Second()
class MyClass {}
3. 元编程与依赖注入
(1)依赖注入示例:框架自动注入 Database 实例
function Injectable(target: any) {// 注册到容器Container.register(target);
}@Injectable
class UserService {constructor(private db: Database) {}
}
四、总结:
1.装饰器的执行顺序
类装饰器最后执行。
方法和访问器装饰器优先于属性装饰器执行。
方法和访问器装饰器按照它们在代码中出现的顺序从下到上执行。
参数装饰器按照它们在参数列表中出现的顺序从左到右执行。
2.装饰器的应用场景
日志记录:如上述例子,在方法调用前后记录日志,方便调试和监控。
权限验证:可以在方法装饰器中实现权限验证逻辑,在调用方法前检查用户权限。