类字段属性的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
相关产品推荐
相关产品推荐

