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

如何在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

关键说明

  1. 避免无限递归:不能在getter中直接访问this[key],否则会再次触发getter导致死循环,这里用Symbol隐藏属性存储实际值,绕过原型上的getter逻辑。
  2. 处理实例属性覆盖:TypeScript的类属性初始化(如color: string = 'red')会在构造阶段触发我们定义的setter,将值存入隐藏属性,不会覆盖原型上的getter。
  3. 装饰器配置:确保TypeScript配置启用装饰器支持,在tsconfig.json中添加:
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:35:22