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

为何第一个JS函数操作复制数组会突变原数组,第二个却不会?

核心原理

JavaScript中的数组属于引用类型,变量存储的不是数组本身的内容,而是数组在堆内存中的存储地址,对数组的操作本质是通过地址访问到实际的数组对象再执行修改。

第一段函数原数组被突变的原因

你写的const copyArr = originalArr并没有生成新的数组副本,只是把原数组的内存地址赋值给了copyArr变量,此时copyArr和originalArr指向内存中的同一个数组对象。
而splice是JS内置的变异方法,会直接修改调用它的数组本身。你通过copyArr调用splice,本质就是修改两个变量共同指向的同一个数组,所以打印originalArr时自然会看到修改后的结果。

function removeSmallest(originalArr) {
  const copyArr = originalArr; // 仅赋值地址,未生成新数组
  console.log(originalArr);
  copyArr.splice(copyArr.indexOf(Math.min(...copyArr)), 1); // 操作的是原数组本身
  console.log(originalArr); // 原数组必然被修改
  return copyArr;
}

第二段函数原数组未被突变的原因

你先通过const copyArr = []创建了一个全新的、内存地址独立的空数组,再通过copyArr.push(...originalArr)把原数组的每一项逐个插入新数组,这一步完成了数组的浅拷贝,最终copyArr和originalArr是两个完全独立的数组对象,内存地址互不关联。
此时你对copyArr调用splice,修改的只是独立的新数组,完全不会影响到原数组,所以原数组不会发生突变。

function removeSmallest(originalArr) {
  const copyArr = [];
  copyArr.push(...originalArr); // 生成独立的新数组副本
  console.log(originalArr);
  copyArr.splice(copyArr.indexOf(Math.min(...copyArr)), 1); // 仅修改新数组
  console.log(originalArr); // 原数组不受影响
  return copyArr;
}

补充:常见的数组浅拷贝方式

除了push(...原数组)之外,以下写法也可以生成独立的数组副本,避免修改原数组:

  • 展开运算符:const copyArr = [...originalArr]
  • slice方法:const copyArr = originalArr.slice()
  • Array.from方法:const copyArr = Array.from(originalArr)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:15:00