如何在JavaScript/TypeScript中为类动态添加getter方法?
可以通过装饰器给Prototype动态添加Getter实现需求
完全可以通过TypeScript的属性装饰器给类的原型添加getter,让实例访问属性时触发自定义逻辑。你的示例代码存在几处问题(getter定义方式错误、无限递归风险、实例属性覆盖原型getter),下面是修正后的可行实现:
正确实现代码
用Object.defineProperty定义原型上的getter/setter,同时借助Symbol创建隐藏属性存储实际值,避免递归问题:
// 用Map存储每个属性对应的隐藏键,避免命名冲突 const hiddenProps = new Map<string, symbol>(); function decorate(target: any, key: string): void { // 为当前属性生成唯一的Symbol作为隐藏属性键 const hiddenKey = Symbol(key); hiddenProps.set(key, hiddenKey); // 在类的原型上定义getter和setter Object.defineProperty(target, key, { get() { console.log(`Accessing property: ${key}`); // 返回隐藏属性中存储的实际值 return this[hiddenKey]; }, set(value) { // 可选:添加属性赋值时的自定义逻辑 console.log(`Setting property: ${key} to ${value}`); this[hiddenKey] = value; }, enumerable: true, configurable: true }); } class Car { @decorate color: string = 'red'; drive(): string { return 'Driving'; } }
测试效果
创建实例并访问/修改属性时:
const car = new Car(); console.log(car.color); car.color = 'blue'; console.log(car.color);
控制台输出:
Setting property: color to red Accessing property: color red Setting property: color to blue Accessing property: color blue
关键说明
- 避免无限递归:不能在getter中直接访问
this[key],否则会再次触发getter导致死循环,这里用Symbol隐藏属性存储实际值,绕过原型上的getter逻辑。 - 处理实例属性覆盖:TypeScript的类属性初始化(如
color: string = 'red')会在构造阶段触发我们定义的setter,将值存入隐藏属性,不会覆盖原型上的getter。 - 装饰器配置:确保TypeScript配置启用装饰器支持,在
tsconfig.json中添加:{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }
内容的提问来源于stack exchange,提问作者Voltterra
相关产品推荐
相关产品推荐

