在 TypeScript 中,装饰器是一种描述类、方法、属性等的元数据的语法。装饰器使得我们可以在类或其成员上绑定一些额外的行为,比如修改某个属性、计算某些值等等。本文将带领大家深入了解 TypeScript 中的装饰器,包括装饰器的基础用法、装饰器的分类以及示例代码。
装饰器的基础用法
在 TypeScript 中使用装饰器时,要在声明前添加 @ 符号,后面跟着一个函数。例如,@decorator,其中 decorator 是一个函数。装饰器函数可以接受一个或多个参数,具体参数的类型和顺序取决于要装饰的目标。
下面是一个简单的装饰器示例:
// www.javascriptcn.com code example
function log(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(`${key} was called`);
}
class MyClass {
@log
myMethod() {
console.log('Hello, world!');
}
}
const myInstance = new MyClass();
myInstance.myMethod();在这个例子中,我们定义了一个名为 log 的装饰器函数。log 装饰器函数接收三个参数,它们分别表示装饰目标的类、属性名和属性描述符。当我们将这个装饰器应用到 myMethod 上时,它会记录 myMethod 方法的调用,然后输出 Hello, world! 。
装饰器的分类
在 TypeScript 中,装饰器可以分为四种类型:类装饰器、方法装饰器、属性装饰器和参数装饰器。它们可以同时出现在一个目标上,并按照以下顺序应用:
- 参数装饰器(从后往前应用)
- 方法装饰器
- 属性装饰器
- 类装饰器(从上往下应用)
下面我们分别介绍每一种类型。
类装饰器
类装饰器用于装饰类声明。类装饰器有一个传入参数,这个参数是一个构造函数。类装饰器可以用来替换构造函数、修改类的行为或元数据。下面是一个示例:
// www.javascriptcn.com code example
function logClass(target: any) {
console.log(`Class name: ${target.name}`);
}
@logClass
class MyClass {
constructor(private name: string) {}
sayHello() {
console.log(`Hello, ${this.name}`);
}
}
const myInstance = new MyClass('World');
myInstance.sayHello();在这个例子中,我们定义了一个名为 logClass 的类装饰器。当我们将 logClass 装饰器应用到 MyClass 上时,它会输出 Class name: MyClass。我们还可以通过修改传入的构造函数的 prototype 属性来增加或修改类的方法。例如,下面的示例在 MyClass 中添加了一个 greet 方法:
// www.javascriptcn.com code example
function addGreet(target: any) {
target.prototype.greet = function() {
console.log(`How are you, ${this.name}`);
};
}
@addGreet
class MyClass {
constructor(private name: string) {}
sayHello() {
console.log(`Hello, ${this.name}`);
}
}
const myInstance = new MyClass('World');
myInstance.sayHello();
myInstance.greet();方法装饰器
方法装饰器用于装饰类的方法。方法装饰器也有一个传入参数,这个参数是一个对象,其中包括类的原型对象、属性名和属性描述符。方法装饰器可以用来修改方法的行为或元数据。下面是一个示例:
// www.javascriptcn.com code example
function logMethod(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(`Method name: ${key}`);
}
class MyClass {
constructor(private name: string) {}
@logMethod
sayHello() {
console.log(`Hello, ${this.name}`);
}
}
const myInstance = new MyClass('World');
myInstance.sayHello();在这个例子中,我们定义了一个名为 logMethod 的方法装饰器。当我们将 logMethod 装饰器应用到 sayHello 上时,它会输出 Method name: sayHello。
属性装饰器
属性装饰器用于装饰类的属性。属性装饰器也有一个传入参数,这个参数是一个对象,其中包括类的原型对象和属性名。属性装饰器可以用来修改属性的行为或元数据。下面是一个示例:
// www.javascriptcn.com code example
function logProperty(target: any, key: string) {
console.log(`Property name: ${key}`);
}
class MyClass {
@logProperty
private name: string;
constructor(name: string) {
this.name = name;
}
sayHello() {
console.log(`Hello, ${this.name}`);
}
}
const myInstance = new MyClass('World');
myInstance.sayHello();在这个例子中,我们定义了一个名为 logProperty 的属性装饰器。当我们将 logProperty 装饰器应用到 name 上时,它会输出 Property name: name。
参数装饰器
参数装饰器用于装饰函数的参数。参数装饰器也有一个传入参数,这个参数是一个对象,其中包括类的原型对象、方法名和参数的索引。参数装饰器可以用来修改参数的行为或元数据。下面是一个示例:
// www.javascriptcn.com code example
function logParam(target: any, methodName: string, index: number) {
console.log(`Parameter ${index} of ${methodName} method in ${target.name} class`);
}
class MyClass {
constructor(private name: string) {}
sayHello(@logParam text: string) {
console.log(`${text}, ${this.name}`);
}
}
const myInstance = new MyClass('World');
myInstance.sayHello('Hello');在这个例子中,我们定义了一个名为 logParam 的参数装饰器。当我们将 logParam 装饰器应用到 text 参数上时,它会输出 Parameter 0 of sayHello method in MyClass class。
结语
本文介绍了 TypeScript 中的装饰器,并分别介绍了四种装饰器类型的用法和示例。虽然 TypeScript 支持装饰器语法,但它并不是 JavaScript 的官方标准,因此在使用装饰器时要注意浏览器和 Node.js 环境的兼容性。当然,在学习和使用装饰器时,我们更应该关注装饰器的设计思想和用法,这些将有助于我们更好地理解类和对象的本质。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6387aa941bf7134be99c8