如何将预定义对象传入类构造函数,使其getter可访问类方法且不重复创建
问题分析
你遇到的核心问题是:massive_entity_obj里的sub_property_b getter中,this指向的是property_1对象,而非Distinct_Class的实例,所以无法调用unique_func_1。同时你需要复用同一个大对象,避免重复创建带来的性能损耗。
下面是几种可行的解决思路:
思路1:动态绑定实例上下文到大对象的getter
在类的构造函数中,重写大对象的getter,把当前实例的上下文绑定进去。注意要设置configurable: true,这样后续实例可以重新覆盖这个getter:
class Distinct_Class { entities = null; constructor(massive_entity_obj) { const self = this; // 重写sub_property_b的getter,绑定当前实例 Object.defineProperty(massive_entity_obj.property_1, 'sub_property_b', { get() { return self.unique_func_1(); }, configurable: true }); this.entities = massive_entity_obj; } unique_func_1() { return `计算结果:来自Distinct_Class实例 ${this}`; } } // 预定义大对象 const massive_entity_obj = { property_1: { sub_property_a: "something" }, }; const distinct_1 = new Distinct_Class(massive_entity_obj) const distinct_2 = new Distinct_Class(massive_entity_obj) console.log(distinct_1.entities.property_1.sub_property_b); console.log(distinct_2.entities.property_1.sub_property_b);
⚠️ 注意:这种方式下,最后一个实例会覆盖大对象的getter,所以如果同时使用多个实例,只有最后一个的上下文会生效。如果需要每个实例都独立关联,就得给每个实例创建大对象的浅拷贝——浅拷贝只会复制对象的引用,不会复制内部的大数据,性能开销可以忽略。
思路2:用Proxy代理大对象,动态关联实例
通过Proxy可以在不修改原大对象的前提下,拦截属性访问,动态关联当前实例的上下文。每个实例的代理都是独立的,不会互相影响:
class Distinct_Class { entities = null; constructor(massive_entity_obj) { const self = this; // 给大对象创建代理 this.entities = new Proxy(massive_entity_obj, { get(target, prop) { if (prop === 'property_1') { // 再给property_1创建代理,处理sub_property_b的访问 return new Proxy(target[prop], { get(obj, subProp) { if (subProp === 'sub_property_b') { return self.unique_func_1(); } return obj[subProp]; } }); } return target[prop]; } }); } unique_func_1() { return `计算结果:来自Distinct_Class实例 ${this}`; } } const massive_entity_obj = { property_1: { sub_property_a: "something" }, }; const distinct_1 = new Distinct_Class(massive_entity_obj) const distinct_2 = new Distinct_Class(massive_entity_obj) console.log(distinct_1.entities.property_1.sub_property_b); console.log(distinct_2.entities.property_1.sub_property_b);
这个方案最灵活,原大对象完全不需要改动,而且每个实例的访问都是独立的,完美满足复用大对象+访问实例方法的需求。
思路3:调整大对象设计,显式传递实例
如果可以修改大对象的结构,让它的方法显式接受实例作为参数,再通过类的封装方法调用,逻辑会更清晰:
// 用工厂函数创建大对象,方法显式接受实例 function createMassiveEntity() { return { property_1: { sub_property_a: "something", getSubPropertyB(instance) { return instance.unique_func_1(); } }, }; } const massive_entity_obj = createMassiveEntity(); class Distinct_Class { entities = null; constructor(massive_entity_obj) { this.entities = massive_entity_obj; } unique_func_1() { return `计算结果:来自Distinct_Class实例 ${this}`; } // 封装访问逻辑,对外隐藏参数传递 get subPropertyB() { return this.entities.property_1.getSubPropertyB(this); } } const distinct_1 = new Distinct_Class(massive_entity_obj) const distinct_2 = new Distinct_Class(massive_entity_obj) console.log(distinct_1.subPropertyB); console.log(distinct_2.subPropertyB);
这种方式没有上下文绑定的坑,代码可读性更高,适合对大对象结构有修改权限的场景。
内容的提问来源于stack exchange,提问作者Occam
相关产品推荐
相关产品推荐

