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

JavaScript构造函数创建新对象继承旧值的原因咨询

问题原因与解决方案:修改User实例属性后影响新实例的问题

这事儿的核心原因是你踩了JavaScript引用类型共享引用的坑,咱们一步步说清楚:

为什么会出现这个问题?

你定义的setup是一个对象(属于引用类型),它在内存中是一个单独的实体。而你的User构造函数里用Object.assign(this, setup),这一步是把setup的属性浅拷贝到新创建的实例上——但这里的关键是:如果你直接复用同一个setup对象,一旦某个操作意外修改了setup本身的属性值,后续所有新创建的User实例都会继承这个被修改后的值。

你可能会疑惑:我修改的是user1.name,为什么会影响setup?大概率是你的简化代码没完全还原真实场景,或者无意中让user1.name直接绑定了setup.name的引用(比如通过getter/setter、嵌套对象等)。但不管怎样,本质都是所有实例共享了同一个数据源对象的引用,导致一个实例的修改会影响全局的setup,进而波及后续的新实例。

怎么解决?

要让每个User实例拥有独立的属性,你需要确保每次创建实例时,都使用一个新的对象副本,而不是复用同一个setup引用。这里有几种简单可行的方案:

方案1:直接在构造函数里定义初始属性

最直观的方式,不需要依赖外部的setup对象:

class User {
  constructor() {
    this.name = '';
  }
}

方案2:每次构造时创建setup的浅拷贝

如果setup的配置需要复用,每次创建实例时都生成一个新的副本,彻底切断引用共享:

const setup = { name: '' };
class User {
  constructor() {
    // 使用扩展运算符创建setup的浅拷贝
    Object.assign(this, {...setup});
    // 也可以用Object.assign创建新对象:Object.assign({}, setup)
  }
}

方案3:用工厂函数生成独立的初始配置

如果setup的逻辑比较复杂,可以写一个工厂函数,每次调用都返回全新的配置对象:

function getSetup() {
  return { name: '' };
}

class User {
  constructor() {
    Object.assign(this, getSetup());
  }
}

这样修改任何一个实例的name属性,都只会影响该实例本身,不会干扰其他新创建的User对象。

内容的提问来源于stack exchange,提问作者Jason Pacini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:37:42