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

不使用扩展运算符在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:25:15