前言
TypeScript中的装饰器是一种特殊的语法,可以用来修改类、方法、属性或参数的行为。装饰器是一种函数,它接收一个目标对象或一个属性描述符作为参数,并可以返回一个新的对象或属性描述符,或者不返回任何值。装饰器可以用来实现一些常见的编程模式,例如依赖注入、日志、缓存、验证等。
使用
要使用装饰器,需要在tsconfig.json文件中设置experimentalDecorators选项为true。装饰器的名称通常以@符号开头,例如@log或@Injectable。装饰器可以应用在类、类的方法、类的属性或类的参数上,分别称为类装饰器、方法装饰器、属性装饰器或参数装饰器。不同类型的装饰器有不同的参数和返回值,具体如下:
-
类装饰器:接收一个类的构造函数作为唯一参数,可以返回一个新的构造函数或不返回任何值。类装饰器可以用来修改或替换类的定义,例如添加新的属性或方法,或改变类的继承关系。
function addProperty(target: any) { target.prototype.newProperty = 'new property'; } @addProperty class MyClass { oldProperty = 'old property'; } const myObject = new MyClass(); console.log(myObject.oldProperty); // 'old property' console.log(myObject.newProperty); // 'new property'
-
方法装饰器:接收三个参数,分别是目标类的原型对象,方法的名称,和方法的属性描述符。可以返回一个新的属性描述符或不返回任何值。方法装饰器可以用来修改或替换方法的定义,例如改变方法的可枚举性,或添加额外的逻辑。
function log(target: any, key: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { console.log(`Calling ${key} with arguments: ${JSON.stringify(args)}`); const result = originalMethod.apply(this, args); console.log(`Result: ${JSON.stringify(result)}`); return result; }; return descriptor; } class MyClass { @log myMethod(arg1: string, arg2: number) { return `${arg1}-${arg2}`; } } const myObject = new MyClass(); myObject.myMethod('hello', 42); // Calling myMethod with arguments: ["hello",42] // Result: "hello-42"
-
属性装饰器:接收两个参数,分别是目标类的原型对象和属性的名称。没有返回值。属性装饰器可以用来修改或替换属性的定义,例如改变属性的可配置性,或定义访问器函数。
function log(target: any, key: string, descriptor: PropertyDescriptor) { const originalGetter = descriptor.get; descriptor.get = function () { console.log(`Getting ${key}`); const result = originalGetter.call(this); console.log(`Result: ${JSON.stringify(result)}`); return result; }; return descriptor; } class MyClass { private _myProperty: string = ''; @log get myProperty() { return this._myProperty; } set myProperty(value: string) { console.log(`Setting myProperty to ${value}`); this._myProperty = value; } } const myObject = new MyClass(); myObject.myProperty = 'hello'; console.log(myObject.myProperty); // Getting myProperty // Result: "hello" // "hello"
-
参数装饰器:接收三个参数,分别是目标类的原型对象,方法的名称,和参数在参数列表中的索引。没有返回值。参数装饰器可以用来注入依赖,或检查参数的类型。
function uppercase(target: any, key: string) { let value = target[key]; const getter = function () { return value; }; const setter = function (newVal: string) { value = newVal.toUpperCase(); }; Object.defineProperty(target, key, { get: getter, set: setter, enumerable: true, configurable: true, }); } class MyClass { @uppercase myProperty: string = ''; } const myObject = new MyClass(); myObject.myProperty = 'hello'; console.log(myObject.myProperty); // 'HELLO'
评论区