装饰器
这个就跟 arkts 中的装饰器很像了
装饰器是一种特殊的声明,它附加到类,方法,属性,访问器等内容上,增加原本组建的内容,行为,为其添加内容
装饰器使用 @expression 这种形式,expression 必须是一个将被调用的函数,它会在运行时被调用,被装饰的声明信息将作为参数传入。
// 定义一个装饰器函数
function logClass(target: Function) {
console.log('Class decorated:', target);
}
// 定义一个装饰器工厂函数
function logParameter(target: Object, propertyKey: string | symbol, parameterIndex: number) {
console.log('Parameter decorated:', target, propertyKey, parameterIndex);
}
// 装饰类
@logClass
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
// 装饰方法参数
greet(@logParameter message: string) {
console.log(`Hello, ${message}`);
}
}
const person = new Person('John');
person.greet('world'); // 输出: Parameter decorated: ... // 输出: Hello, world
在这个示例中:
- logClass 是一个装饰器函数,它会在编译期间被调用,并将被装饰的类作为参数传入。
- logParameter 是一个装饰器工厂函数,它返回一个装饰器,用于装饰方法参数。
- 使用 @logClass 语法将 logClass 装饰器应用到 Person 类上。
- 使用 @logParameter 语法将 logParameter 装饰器应用到 greet 方法的 message 参数上。
装饰器的执行顺序是从上到下,从右到左。当实例化 Person 类时,会先执行 logClass 装饰器,输出 Class decorated: ...。当调用 greet 方法时,会先执行 logParameter 装饰器,输出 Parameter decorated: ...。
类装饰器
function Sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@Sealed
class Greeter {
constructor(public greeting: string) {}
greet() {
return "Hello, " + this.greeting;
}
}
方法装饰器
function Log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
let originalMethod = descriptor.value; // 保存原始函数
descriptor.value = function (...args: any[]) {
console.log("Arguments: ", JSON.stringify(args));
let result = originalMethod.apply(this, args);
console.log("Result: ", result);
return result;
}
}
class Calculator {
@Log
add(x: number, y: number): number {
return x + y;
}
}
访问器装饰器
function ReadOnly(target: any, key: string, descriptor: PropertyDescriptor) {
descriptor.writable = false;
return descriptor;
}
class Circle {
private _radius: number;
constructor(radius: number) {
this._radius = radius;
}
@ReadOnly
get radius() {
return this._radius;
}
}