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

扩展运算符(Spread operator)在数组与对象中的行为是否存在差异?

理解扩展运算符的浅拷贝行为:数组基本类型 vs 引用类型

这是个典型的JavaScript浅拷贝问题,咱们来把这个现象拆解明白:

先修正你代码里的小笔误

你代码里有几个拼写错误,比如console.log(copy)应该是console.log(copiedArray),arr应该是array,修正后的完整代码是:

const array = [12,40,63,21,22,32];
const copiedArray = [...array];
console.log(copiedArray);
array[0] = 92;
console.log(array, copiedArray);

const p1 = [{name:'Arabh' , age:39} ,{name:'Sana' , age:33}];
const p2 = [...p1];
p1[0].name = 'Samir';
console.log(p1,p2);

为什么两种场景表现不同?

核心原因是扩展运算符实现的是浅拷贝,它对数组元素的处理方式取决于元素的类型:

  • 基本类型(数字、字符串、布尔值等):这些类型的值直接存在栈内存里,扩展运算符会复制它们的实际值到新数组。所以当你修改原数组的array[0]时,只是改变了原数组对应位置的值,新数组copiedArray里保存的是原来的12,不会跟着变化。
  • 引用类型(对象、数组等):这些类型的实际数据存在堆内存,变量里保存的是指向堆内存的引用地址。扩展运算符复制的只是这个引用地址,所以p1[0]和p2[0]指向的是同一个堆内存里的对象。当你修改p1[0].name时,其实是在修改堆内存里那个对象的属性,两个数组里的引用都指向这个对象,所以都会看到变化。

如何实现深拷贝(让对象数组修改原对象不影响新数组)

如果想要完全复制对象数组,让原对象和新对象互不影响,可以用这些方法:

  • 简单场景用JSON.parse(JSON.stringify(数组)):注意这个方法不能处理函数、Symbol类型、循环引用的对象
  • 手写递归深拷贝函数,遍历每个元素,遇到引用类型就递归复制
  • 用成熟的工具库,比如Lodash的_.cloneDeep方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:57:40