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

使用Object.assign时原对象值被覆盖,如何安全修改person1.name.first?

解决Object.assign()修改嵌套属性时覆盖原对象的问题

嘿,这个问题我太熟了!Object.assign()的坑就在于它是浅拷贝——只会复制对象的顶层属性,嵌套的对象还是共享同一个引用,所以你修改新对象的嵌套属性时,原蓝图对象也跟着变了。要保护原对象不被修改,我们需要确保嵌套层级的对象也是新的副本,下面给你几个实用的解决方案:

方案1:用展开运算符(...)逐层拷贝嵌套对象

如果你的对象嵌套层级不多,这种方式最清晰,能精准控制要修改的属性:

假设你的蓝图对象是这样的:

const blueprintPerson = {
  name: {
    first: "John",
    last: "Doe"
  },
  age: 30
};

要创建修改name.first后的person1,同时不改动原蓝图:

const person1 = {
  // 先拷贝顶层所有属性
  ...blueprintPerson,
  // 单独处理name属性:先拷贝原name的所有属性,再覆盖first
  name: {
    ...blueprintPerson.name,
    first: "Jane"
  }
};

这样person1.name是一个全新的对象,和blueprintPerson.name不再共享引用,修改person1.name.first完全不会影响原蓝图。

方案2:用structuredClone()做深拷贝

如果你的对象嵌套层级比较深,或者不想手动逐层展开,用ES2022新增的structuredClone()最省心,它能递归复制整个对象的所有层级:

const person1 = structuredClone(blueprintPerson);
// 现在随便修改嵌套属性,原蓝图毫发无损
person1.name.first = "Jane";

这个方法支持大多数数据类型(对象、数组、Date、Map等),现代浏览器和Node.js 17+都支持,简单粗暴还靠谱。

方案3:自定义深拷贝函数(兼容旧环境)

如果需要兼容不支持structuredClone()的旧环境,可以自己写一个简单的深拷贝函数:

function deepClone(obj) {
  // 非对象类型直接返回
  if (obj === null || typeof obj !== "object") return obj;
  // 处理Date对象
  if (obj instanceof Date) return new Date(obj.getTime());
  // 处理数组
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  // 处理普通对象
  const clonedObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  return clonedObj;
}

// 使用方式
const person1 = deepClone(blueprintPerson);
person1.name.first = "Jane";

总结一下:如果只是修改少数嵌套属性,优先用展开运算符(代码可读性高);如果对象复杂,直接用structuredClone();旧环境就用自定义深拷贝函数。这三种方法都能彻底保护你的蓝图对象不被修改。

内容的提问来源于stack exchange,提问作者Tpn Knvl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:40:08