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

JavaScript:浅拷贝数组两种修改行为的差异原因及原数组防护方法

嘿,这个问题其实戳中了JavaScript里浅拷贝和引用类型的核心点,我给你掰扯明白~

为什么两种场景结果天差地别?

首先得搞懂:数组的浅拷贝(比如用[...arr]、slice()或者Object.assign()),只会拷贝数组本身的第一层结构——但数组里的对象是引用类型,浅拷贝拷贝的只是指向内存中对象的“指针”,不是对象本身。

场景1:修改浅拷贝元素会影响原数组

先看你的代码逻辑:

var peopleOriginal = [{name: 'alex', age:999 }];
var peopleCopy = [...peopleOriginal]; // 浅拷贝数组
peopleCopy[0].age = 100; // 修改拷贝数组里的对象属性
console.log(peopleOriginal[0].age); // 输出100,原数组被改了

原因很简单:peopleCopy[0]和peopleOriginal[0]指向的是内存里同一个对象。你修改的是这个对象的属性,本质是在改内存里的那个“实体”,两个数组的元素都指着它,自然都会看到变化。

场景2:给浅拷贝赋值空数组不影响原数组

再看这个场景:

var peopleOriginal = [{name: 'alex', age:999 }];
var peopleCopy = [...peopleOriginal];
peopleCopy = []; // 直接给拷贝变量赋值新数组
console.log(peopleOriginal); // 还是[{name: 'alex', age:999 }]

这里你不是在修改原来的拷贝数组,而是给peopleCopy这个变量重新分配了一个全新的数组引用。原来的浅拷贝数组和原数组的关联直接断了——peopleOriginal还指着原来的数组,peopleCopy现在指着空数组,两者完全没关系了,原数组当然不受影响。

你忽略的逻辑就是:浅拷贝只处理数组的第一层,嵌套的引用类型(对象、数组)拷贝的是引用;而直接给变量赋值新数组,是改变变量的引用指向,不是修改原引用的内容。

怎么实现修改拷贝不影响原数组?

要解决这个问题,你需要做深拷贝——不仅拷贝数组本身,还要把数组里的每个对象也完整复制一份,让它们指向不同的内存地址。给你几种常用方案:

方法1:手动遍历拷贝(适合简单结构)

如果数组里只有一层对象,直接遍历数组,逐个拷贝每个对象就行:

var peopleOriginal = [{name: 'alex', age:999 }];
var peopleCopy = peopleOriginal.map(person => {
  // 用对象展开语法或者Object.assign拷贝单个对象
  return {...person};
  // 也可以写 return Object.assign({}, person);
});
peopleCopy[0].age = 100;
console.log(peopleOriginal[0].age); // 输出999,原数组没变化

方法2:JSON序列化/反序列化(适合纯数据对象)

这种方法简单粗暴,但有局限性——如果对象里有函数、Symbol、undefined或者循环引用,会丢失数据或报错,只适合纯数据结构:

var peopleOriginal = [{name: 'alex', age:999 }];
var peopleCopy = JSON.parse(JSON.stringify(peopleOriginal));
peopleCopy[0].age = 100;
console.log(peopleOriginal[0].age); // 输出999

方法3:用第三方库(适合复杂场景)

如果你的项目已经引入了Lodash,直接用cloneDeep最省心,能处理各种嵌套结构和特殊类型:

var peopleOriginal = [{name: 'alex', age:999 }];
var peopleCopy = _.cloneDeep(peopleOriginal);
peopleCopy[0].age = 100;
console.log(peopleOriginal[0].age); // 输出999

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:11:00