Appearance
reflect-metadata #
reflect-metadata
是一个用于在 JavaScript 和 TypeScript 中实现元编程的库。它通过提供元数据反射 API,允许开发者在运行时检查和操作对象的元数据。元数据可以看作是关于程序结构的额外信息,比如类、属性或方法的注解。
核心概念 #
元数据 (Metadata):
- 元数据是附加在程序元素(如类、方法、属性等)上的信息,可以在运行时通过反射 API 获取和操作。
反射 (Reflection):
- 反射是一种能力,使得程序可以在运行时检查自身的结构,并对其进行修改或操作。
reflect-metadata
的基本功能
定义元数据:
- 使用
Reflect.defineMetadata
方法定义元数据。
typescriptimport 'reflect-metadata'; Reflect.defineMetadata('role', 'admin', target);
1
2
3
4- 使用
获取元数据:
- 使用
Reflect.getMetadata
方法获取元数据。
typescriptconst role = Reflect.getMetadata('role', target); console.log(role); // 'admin'
1
2
3- 使用
检查元数据:
- 使用
Reflect.hasMetadata
方法检查是否存在指定的元数据。
typescriptconst hasRoleMetadata = Reflect.hasMetadata('role', target); console.log(hasRoleMetadata); // true
1
2
3- 使用
删除元数据:
- 使用
Reflect.deleteMetadata
方法删除元数据。
typescriptReflect.deleteMetadata('role', target); const hasRoleMetadata = Reflect.hasMetadata('role', target); console.log(hasRoleMetadata); // false
1
2
3
4- 使用
应用示例 #
以下是一些使用 reflect-metadata
的常见场景和示例代码:
类装饰器:
- 使用装饰器为类添加元数据。
typescriptimport 'reflect-metadata'; @Reflect.metadata('role', 'admin') class User { constructor(public name: string) {} } const role = Reflect.getMetadata('role', User); console.log(role); // 'admin'
1
2
3
4
5
6
7
8
9
10方法装饰器:
- 使用装饰器为方法添加元数据。
typescriptimport 'reflect-metadata'; class UserService { @Reflect.metadata('role', 'admin') getUser() {} } const role = Reflect.getMetadata('role', UserService.prototype, 'getUser'); console.log(role); // 'admin'
1
2
3
4
5
6
7
8
9
10参数装饰器:
- 使用装饰器为方法参数添加元数据。
typescriptimport 'reflect-metadata'; class UserService { getUser(@Reflect.metadata('required', true) id: number) {} } const requiredMetadata = Reflect.getMetadata('required', UserService.prototype, 'getUser'); console.log(requiredMetadata); // true
1
2
3
4
5
6
7
8
9属性装饰器:
- 使用装饰器为类属性添加元数据。
typescriptimport 'reflect-metadata'; class User { @Reflect.metadata('format', 'email') email: string; } const formatMetadata = Reflect.getMetadata('format', User.prototype, 'email'); console.log(formatMetadata); // 'email'
1
2
3
4
5
6
7
8
9
10
完整示例 #
以下是一个综合使用 reflect-metadata
的示例,展示如何为类、方法和属性添加元数据并在运行时进行操作:
typescript
import 'reflect-metadata';
// 类装饰器
function Role(role: string) {
return Reflect.metadata('role', role);
}
// 方法装饰器
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with arguments:`, args);
return originalMethod.apply(this, args);
};
}
// 属性装饰器
function Format(format: string) {
return Reflect.metadata('format', format);
}
@Role('admin')
class User {
@Format('email')
email: string;
constructor(email: string) {
this.email = email;
}
@Log
getUserInfo() {
return `User email: ${this.email}`;
}
}
const user = new User('test@example.com');
// 获取类的元数据
const role = Reflect.getMetadata('role', User);
console.log(`Role: ${role}`); // 'Role: admin'
// 获取属性的元数据
const emailFormat = Reflect.getMetadata('format', User.prototype, 'email');
console.log(`Email format: ${emailFormat}`); // 'Email format: email'
// 调用方法,触发日志输出
console.log(user.getUserInfo());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
结论 #
reflect-metadata
提供了一种在 JavaScript 和 TypeScript 中实现元编程的方法,使得开发者可以通过装饰器和反射 API 添加、获取和操作元数据。这在构建复杂的框架和库时非常有用,如依赖注入、路由、验证等场景。通过掌握 reflect-metadata
的使用,可以更灵活地控制和扩展应用程序的行为。