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

类字段属性的getter/setter中this使用及子属性定义方案

在类字段的子属性中实现指向类实例的Getter/Setter(无需构造函数)

我希望将getter和setter定义为类字段属性的子属性,保持多层级结构,但无法让this指向类实例数据。已知用构造函数+self可以解决,但不想在构造函数里写这些定义;也可以用函数调用代替getter/setter,但希望保留语法特性。之前尝试的代码会触发递归错误(因为getter里的this指向子属性对象而非类实例),以下是两种无需构造函数、保留多层结构且正确绑定this的实现方式:

方案1:箭头函数 + Object.defineProperties

class data_controller {
  id = 12;
  a = 10;
  b = 20;

  log = {
    entry: Object.defineProperties({}, {
      a: {
        get: () => ({
          id: this.id,
          value: this.a,
          label: 'a'
        })
      },
      b: {
        get: () => ({
          id: this.id,
          value: this.b,
          label: 'b'
        })
      }
    })
  };

  update = Object.defineProperties({}, {
    a: {
      set: (value) => {
        this.a = value;
      }
    },
    b: {
      set: (value) => {
        this.b = value;
      }
    }
  });
}

// 使用示例
const data = new data_controller();
console.log(data.log.entry.a); // { id: 12, value: 10, label: 'a' }
console.log(data.log.entry.b); // { id: 12, value: 20, label: 'b' }
data.update.a = 50;
data.update.b = 60;
console.log(data.log.entry.a); // { id: 12, value: 50, label: 'a' }
console.log(data.log.entry.b); // { id: 12, value: 60, label: 'b' }

说明

  • 类字段中的箭头函数会词法绑定类实例的this,所以getter/setter里的this直接指向类实例,不会指向entry或update对象。
  • 用Object.defineProperties替代对象字面量的get/set语法,避免this指向错误导致的递归问题。

方案2:私有字段保存类实例引用

class data_controller {
  id = 12;
  a = 10;
  b = 20;

  // 私有字段保存类实例的this,避免全局污染
  #self = this;

  log = {
    entry: {
      get a() {
        return {
          id: this.#self.id,
          value: this.#self.a,
          label: 'a'
        };
      },
      get b() {
        return {
          id: this.#self.id,
          value: this.#self.b,
          label: 'b'
        };
      }
    }
  };

  update = {
    set a(value) {
      this.#self.a = value;
    },
    set b(value) {
      this.#self.b = value;
    }
  };
}

说明

  • 私有字段#self仅在类内部可访问,安全地保存了类实例的引用。
  • getter/setter里通过this.#self直接访问类实例的属性,既保留了对象字面量的get/set语法,又避免了this指向子对象的问题。

原代码报错原因

你最初的代码中,log.entry.a的getter里的this指向的是entry对象本身,所以this.a会再次触发这个getter,导致无限递归最终栈溢出。上面的两种方案都让访问路径指向了类实例,解决了递归问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:32:14