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

TypeScript中使用Property装饰器无法访问属性值的问题

属性装饰器中获取到属性值为undefined的原因及解决方案

问题原因

属性装饰器的执行时机是类被定义的阶段,而非类实例化的阶段。此时:

  • 你装饰的是实例属性,target参数指向的是类的原型对象,不是类的实例
  • 实例属性的初始化赋值(="Siddu Rocks")是在类的构造函数执行时才会完成,也就是只有当你创建DecoratorClass的实例时,这个值才会被赋值到实例对象上
  • 类定义阶段,原型对象上并没有property1这个属性,所以target[propertyName]返回undefined

解决方案

如果你想获取到属性的初始值,有三种常用思路:

1. 拦截属性的getter/setter捕获赋值时刻的值

修改属性装饰器,利用Object.defineProperty重写属性的访问器,这样在属性被赋值时就能捕获到值:

class DecoratorClass{
  @HelloWorld
  public property1:string="Siddu Rocks"
}

function HelloWorld(target:any, propertyName:string){
    let storedValue: string;
    // 重写属性的getter和setter
    Object.defineProperty(target, propertyName, {
        get() {
            return storedValue;
        },
        set(newValue: string) {
            storedValue = newValue;
            console.log(`The Class Target and prop names are: ${storedValue}, ${propertyName}`);
        },
        enumerable: true,
        configurable: true
    });
}

const instance = new DecoratorClass();
// 输出:The Class Target and prop names are: Siddu Rocks, property1

2. 实例化后直接访问属性值

如果不需要在装饰器执行时获取值,而是想验证属性的最终值,可以在创建类实例后直接访问:

class DecoratorClass{
  @HelloWorld
  public property1:string="Siddu Rocks"
}

function HelloWorld(target:any, propertyName:string){
    console.log(`装饰器执行时:${target[propertyName]}, ${propertyName}`);
}

const instance = new DecoratorClass();
console.log(`实例化后:${instance.property1}, property1`);
// 输出:
// 装饰器执行时:undefined, property1
// 实例化后:Siddu Rocks, property1

3. 用类装饰器捕获实例化后的属性

通过类装饰器包装原类的构造函数,在实例化完成后获取属性值:

function TrackProperty(constructor: Function) {
    const originalConstructor = constructor;
    // 包装构造函数
    const newConstructor: any = function(...args: any[]) {
        const instance = new originalConstructor(...args);
        console.log(`The Class Target and prop names are: ${instance.property1}, property1`);
        return instance;
    }
    // 保留原类的原型链
    newConstructor.prototype = originalConstructor.prototype;
    return newConstructor;
}

@TrackProperty
class DecoratorClass{
  public property1:string="Siddu Rocks"
}

const instance = new DecoratorClass();
// 输出:The Class Target and prop names are: Siddu Rocks, property1

内容的提问来源于stack exchange,提问作者Siddarth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:30:49