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
相关产品推荐
相关产品推荐

