如何在父类方法装饰器中获取实际运行的子类类名?
问题:方法装饰器输出抽象父类名称,而非实际运行的子类名称
我编写了一个方法装饰器用于记录类的相关信息,整体运行符合预期,但存在一个问题:我希望它记录实际运行的类的名称,然而当前它输出的是抽象父类的名称。
原装饰器代码
const logClassName: MethodDecorator = ( target: any, _propertyKey: string, _descriptor: PropertyDescriptor, ) => { console.log(`class name from decorator: ${target.constructor.name}`); };
类定义
abstract class AbstractClass { @logClassName logClassName() { console.log(`class name from function : ${this.constructor.name}`) } } class ConcreteClass extends AbstractClass {}
执行代码
const concrete = new ConcreteClass(); concrete.logClassName();
当前输出
class name from decorator: AbstractClass class name from function : ConcreteClass
我期望两条日志都输出ConcreteClass,至少保持一致。
解决方案
问题核心在于装饰器的执行时机:装饰器是在类定义阶段执行的,此时target指向抽象父类的原型对象,因此获取到的是父类的构造函数名称。要获取运行时的子类名称,需要将打印逻辑移到方法调用时执行。
修改后的装饰器代码
const logClassName: MethodDecorator = ( target: any, _propertyKey: string, descriptor: PropertyDescriptor, ) => { // 保存原方法的引用 const originalMethod = descriptor.value; // 重写方法,注入运行时逻辑 descriptor.value = function(...args: any[]) { // 此时this指向调用方法的实例(子类实例) console.log(`class name from decorator: ${this.constructor.name}`); // 调用原方法并传递上下文和参数 return originalMethod.apply(this, args); }; return descriptor; };
修改后执行输出
class name from decorator: ConcreteClass class name from function : ConcreteClass
逻辑说明
- 原装饰器在类定义时直接打印,此时子类尚未完成继承,只能拿到父类的构造函数信息。
- 修改后通过重写原方法,将打印逻辑延迟到方法运行时执行,此时
this指向实际调用方法的子类实例,因此this.constructor.name可以正确获取子类名称。
内容的提问来源于stack exchange,提问作者Rodrigo Sasaki
相关产品推荐
相关产品推荐

