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

如何避免修改对象内部数组的对象字段时篡改原对象?

解决对象深拷贝问题:修改嵌套属性不影响原对象

你遇到的核心问题是浅拷贝的局限性:Object.assign()和扩展运算符(...)仅复制对象的顶层属性,对于嵌套的数组、对象这类引用类型,它们复制的是内存地址而非实际内容。这就导致修改拷贝后的嵌套属性时,原对象会同步被修改。

以下是几种可行的深拷贝解决方案:

1. 手动实现深拷贝

通过递归遍历对象的每一层属性,对引用类型进行逐层复制:

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

// 测试使用
const originalObject = {
  name: "John Doe",
  age: 30,
  arr: [{ num: 1 }]
};

const copied = deepClone(originalObject);
copied.arr[0].num = 2;
console.log(originalObject.arr[0].num); // 输出1,原对象未被修改

2. 使用JSON序列化/反序列化

这是最简便的方式,但存在局限性:无法拷贝函数、Symbol、循环引用,以及Date、RegExp这类特殊对象会被转成字符串或普通对象:

const copied = JSON.parse(JSON.stringify(originalObject));
copied.arr[0].num = 2;
console.log(originalObject.arr[0].num); // 输出1

3. 原生结构化克隆(Structured Clone)

现代浏览器和Node.js(v17+)原生支持的API,能处理更多类型(Date、RegExp、Map、Set等),但仍不支持函数:

// 浏览器环境
const copied = structuredClone(originalObject);

// Node.js环境
const { structuredClone } = require('node:util');
const copied = structuredClone(originalObject);

copied.arr[0].num = 2;
console.log(originalObject.arr[0].num); // 输出1

4. 使用第三方库(如Lodash)

如果项目已引入Lodash,直接使用成熟的深拷贝方法:

const _ = require('lodash');
const copied = _.cloneDeep(originalObject);
copied.arr[0].num = 2;
console.log(originalObject.arr[0].num); // 输出1

方法选择建议

  • 若需自定义拷贝逻辑或无依赖场景:手动实现深拷贝
  • 简单场景且无特殊类型:JSON序列化方案
  • 现代环境且需支持更多类型:结构化克隆API
  • 复杂项目或已有Lodash依赖:使用_.cloneDeep

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:45:01