返回
TypeScript 入门学习——类以及类的装饰器
前端
2023-10-25 17:58:11
TypeScript 类与装饰器简介
TypeScript中的类与传统JavaScript中的类非常相似,它们都可以定义属性和方法。不同之处在于,TypeScript中的类是强类型的,并且支持访问控制和继承。TypeScript中的装饰器是一种元编程技术,允许我们在类声明和成员(例如,方法、属性和访问器)上附加额外信息。这些信息可以通过运行时反射进行访问和使用,从而可以对类的行为进行修改或扩展。
类装饰器
类装饰器用于修饰整个类,它可以用来为类添加元数据、修改类的行为,或添加额外的特性。
类装饰器的语法
@decorator
class MyClass {
// ...
}
在这个例子中,@decorator
是装饰器,它被用于修饰MyClass
类。装饰器可以是函数或类。
类装饰器的示例
以下是类装饰器的一些示例:
- 日志装饰器 :该装饰器用于在类的方法执行前后打印日志。
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with args ${args}`);
const result = originalMethod.apply(this, args);
console.log(`Called ${propertyKey} with result ${result}`);
return result;
};
}
@log
class MyClass {
sayHello(name: string) {
return `Hello, ${name}!`;
}
}
const myClass = new MyClass();
myClass.sayHello("World");
- 属性校验装饰器 :该装饰器用于检查属性的值是否符合预期的条件。
function validate(condition: Function) {
return function(target: any, propertyKey: string) {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
if (descriptor) {
const originalSet = descriptor.set;
descriptor.set = function(value: any) {
if (condition(value)) {
originalSet?.call(this, value);
} else {
throw new Error("Invalid value");
}
};
}
};
}
class MyClass {
@validate((value: number) => value >= 0)
private _age: number;
get age() {
return this._age;
}
set age(value: number) {
this._age = value;
}
}
const myClass = new MyClass();
myClass.age = 20;
console.log(myClass.age); // 20
myClass.age = -1;
console.log(myClass.age); // Error: Invalid value
方法装饰器
方法装饰器用于修饰类中的方法,它可以用来在方法执行前后添加逻辑、修改方法的行为,或添加额外的特性。
方法装饰器的语法
class MyClass {
@decorator
methodName(args: any) {
// ...
}
}
在这个例子中,@decorator
是装饰器,它被用于修饰methodName
方法。装饰器可以是函数或类。
方法装饰器的示例
以下是方法装饰器的一些示例:
- 计时装饰器 :该装饰器用于计算方法的执行时间。
function timing(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
const start = performance.now();
const result = originalMethod.apply(this, args);
const end = performance.now();
console.log(`Method ${propertyKey} took ${end - start} milliseconds to execute.`);
return result;
};
}
class MyClass {
@timing
sayHello(name: string) {
return `Hello, ${name}!`;
}
}
const myClass = new MyClass();
myClass.sayHello("World");
- 参数校验装饰器 :该装饰器用于检查方法参数的值是否符合预期的条件。
function validate(condition: Function) {
return function(target: any, propertyKey: string, parameterIndex: number) {
const originalMethod = target[propertyKey];
target[propertyKey] = function(...args: any[]) {
if (condition(args[parameterIndex])) {
return originalMethod.apply(this, args);
} else {
throw new Error("Invalid argument");
}
};
};
}
class MyClass {
method(
@validate((value: number) => value >= 0)
x: number,
@validate((value: number) => value < 10)
y: number
) {
return x + y;
}
}
const myClass = new MyClass();
myClass.method(5, 3); // 8
myClass.method(5, 11); // Error: Invalid argument
属性装饰器
属性装饰器用于修饰类中的属性,它可以用来在属性访问时添加逻辑、修改属性的行为,或添加额外的特性。
属性装饰器的语法
class MyClass {
@decorator
propertyName: type;
}
在这个例子中,@decorator
是装饰器,它被用于修饰propertyName
属性。装饰器可以是函数或类。
属性装饰器的示例
以下是属性装饰器的一些示例:
- 只读装饰器 :该装饰器用于将属性设置为只读。
function readOnly(target: any, propertyKey: string) {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
if (descriptor) {
descriptor.writable = false;
}
}
class MyClass {
@readOnly
name: string;
constructor(name: string) {
this.name = name;
}
}
const myClass = new MyClass("John");
myClass.name = "Mary"; // Error: Cannot assign to read only property 'name'
- 类型检查装饰器 :该装饰器用于检查属性值是否符合预期的类型。
function checkType(type: Function) {
return function(target: any, propertyKey: string) {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
if (descriptor) {
const originalSet = descriptor.set;
descriptor.set = function(value: any) {
if (typeof value === type) {
originalSet?.call(this, value);
} else {
throw new Error("Invalid type");
}
};
}
};
}
class MyClass {
@checkType(String)
name: string;
constructor(name: string) {
this.name = name;
}
}
const myClass = new MyClass("John");
myClass.name = "Mary"; // OK
myClass.name = 123; // Error: Invalid type
访问器装饰器
访问器装饰器用于修饰类中的访问器,它可以用来在访问器访问时添加逻辑、修改访问器行为,或添加额外的特性。
访问器装饰器的语法
class MyClass {
@decorator
get propertyName(): type;
@decorator
set propertyName(value: type);
}
在这个例子中,@decorator
是装饰器,它被用于修饰propertyName
访问器。装饰器可以是函数或类。
访问器装饰器的示例
以下是访问器装饰器的一些示例:
- 只读访问器装饰器 :该装饰器用于将访问器设置为只读。
function readOnly(target: any, propertyKey: string) {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
if (descriptor) {
descriptor.set = undefined;
}
}
class MyClass {
@readOnly
get name(): string {
return this._name;
}
private _name: string;
constructor(name: string) {
this._name = name;
}
}
const myClass = new MyClass("