不使用扩展运算符在ES6类中实现原型模式遇问题求助
解决ES6类中无扩展运算符实现原型模式的问题
我帮你找出问题所在了——你遇到的核心问题是对象引用共享,导致修改克隆实例的options时,原型的options也被意外修改了。咱们一步步拆解并解决:
问题根源
你的构造函数里直接把传入的options赋值给实例属性:
this.options = options;
这意味着所有通过这个构造函数创建的实例(包括原型实例和克隆实例),它们的options属性都指向同一个对象(也就是你定义的var options = { width : 200, height: 100 })。
- 使用扩展运算符
{...clone.options, ...features}时,你是创建了一个全新的对象,然后把这个新对象赋值给clone.options,这时候克隆实例的options就和原型的彻底分开了。 - 但改用
Object.assign(clone.options, features)时,你是直接在共享的原对象上修改属性,所以原型实例的options也会被同步修改,这就完全不符合原型模式“克隆出独立对象”的预期。
修正方案(两种可选)
我们需要确保每个实例的options都是独立的对象,避免引用共享。以下两种方案都能解决问题,且不需要使用扩展运算符:
方案1:构造函数内浅拷贝options(推荐)
在构造函数中就对传入的options做浅拷贝,从根源上避免引用共享:
class Prototype { constructor(options) { // 用Object.assign创建新对象,拷贝传入的options属性 this.options = Object.assign({}, options); this.context = undefined; } clone(features) { let clone = new Prototype(this.options); // 同样用Object.assign创建新对象,合并现有options和新特性 clone.options = Object.assign({}, clone.options, features); return clone; } } // 测试代码 var options = { width : 200, height: 100 } let prototype = new Prototype(options); let clone = prototype.clone({ height: 800, color: "red" } ); console.log("prototype options:", prototype.options); // { width: 200, height: 100 } console.log("clone options:", clone.options); // { width: 200, height: 800, color: "red" }
方案2:在clone方法中直接创建合并后的新对象
如果不想修改构造函数,也可以在clone方法里直接合并出全新的options,再用它创建克隆实例:
class Prototype { constructor(options) { this.options = options; this.context = undefined; } clone(features) { // 合并原型的options和新features,创建一个完全独立的新对象 const mergedOptions = Object.assign({}, this.options, features); // 用新对象创建克隆实例 let clone = new Prototype(mergedOptions); return clone; } } // 测试代码 var options = { width : 200, height: 100 } let prototype = new Prototype(options); let clone = prototype.clone({ height: 800, color: "red" } ); console.log("prototype options:", prototype.options); // { width: 200, height: 100 } console.log("clone options:", clone.options); // { width: 200, height: 800, color: "red" }
针对你的场景说明
因为你要创建1000万颗星星,这里的浅拷贝(Object.assign({}, obj))完全足够——只要你的options里没有嵌套的对象/数组,浅拷贝就能保证每个星星的配置都是独立的,而且性能开销极低,不会影响大规模创建的效率。
内容的提问来源于stack exchange,提问作者Gildas.Tambo
相关产品推荐
相关产品推荐

