You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在父类方法装饰器中获取实际运行的子类类名?

问题:方法装饰器输出抽象父类名称,而非实际运行的子类名称

我编写了一个方法装饰器用于记录类的相关信息,整体运行符合预期,但存在一个问题:我希望它记录实际运行的类的名称,然而当前它输出的是抽象父类的名称。

原装饰器代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:12:35