JavaScript 数组复制
·
在 JavaScript 中,数组是 引用类型。如果直接赋值,会导致两个变量指向同一个数组,修改其中一个会影响另一个。
const arr1 = [1, 2, 3];
const arr2 = arr1; // 只是引用
arr2[0] = 100;
console.log(arr1); // [100, 2, 3] 也被修改了
为了方便后续翻阅,所以这篇文章整理一下 数组复制 相关概念,并区分:
- 浅拷贝(Shallow Copy):只复制第一层,内部对象仍是引用。
- 深拷贝(Deep Copy):完全复制,包括内部对象。
一、浅拷贝(Shallow Copy)
浅拷贝适用于 数组元素为基本类型(数字、字符串、布尔值等)的情况。如果数组里有对象,复制的只是对象的引用,修改副本会影响原数组。
常见方法
1. slice()
slice() 方法会返回一个新数组,其中包含从原始数组中选取的元素。不带参数时,它会复制整个数组。
const arr = [1, 2, 3];
const copy = arr.slice();
2. concat()
concat() 方法用于合并两个或多个数组。通过将一个空数组与目标数组合并,可以实现浅拷贝。
const arr = [1, 2, 3];
const copy = [].concat(arr);
3. 展开运算符 ...
const arr = [1, 2, 3];
const copy = [...arr];
4. Array.from()
此方法从一个类似数组或可迭代对象中创建一个新的、浅拷贝的数组实例。
const arr = [1, 2, 3];
const copy = Array.from(arr);
示例:浅拷贝对对象无效
const arr = [{ a: 1 }, { b: 2 }];
const copy = [...arr];
copy[0].a = 100;
console.log(arr[0].a); // 100,原数组也被修改!
二、深拷贝(Deep Copy)
深拷贝会复制整个数组,包括里面的对象。修改副本不会影响原数组。
常见方法
1. JSON 方法(简易深拷贝)
这是一种简单的深拷贝方法。它通过将数组转换为 JSON 字符串,然后再解析回新的 JavaScript 对象来工作。
const arr = [{ a: 1 }, { b: 2 }];
const copy = JSON.parse(JSON.stringify(arr));
copy[0].a = 100;
console.log(arr[0].a); // 1
缺点: 此方法无法处理函数、undefined、Symbol 值或循环引用。它只适用于简单、可序列化的 JSON 数据。
2. structuredClone(推荐)
structuredClone() 是现代 JavaScript 中推荐的深拷贝方法。它能处理多种数据类型,包括对象、数组、Map、Set,甚至循环引用。
const arr = [{ a: 1 }, { b: 2 }];
const copy = structuredClone(arr);
copy[0].a = 100;
console.log(arr[0].a); // 1
- 优点:支持对象、数组、
Map、Set、循环引用等。 - 需要现代浏览器或 Node.js 17+。
三、方法对比
| 方法 | 类型 | 支持度 | 适用场景 |
|---|---|---|---|
slice() / concat() |
浅拷贝 | 全支持 | 简单复制(针对基本类型) |
展开运算符 ... |
浅拷贝 | ES6+ | 写法简洁 |
Array.from() |
浅拷贝 | ES6+ | 转换类数组对象或可迭代对象 |
JSON.parse(JSON.stringify()) |
深拷贝(有限制) | 全支持 | 适合 JSON 数据 |
structuredClone() |
深拷贝 | 现代环境 | 推荐,最强 |
四、总结
- 浅拷贝:只复制数组的第一层。它性能更好,适用于只包含基本数据类型的数组。
- 深拷贝:会创建一个完全独立的副本,包括所有嵌套对象。当你处理复杂、嵌套的数据并需要确保副本与原数组完全隔离时,应使用深拷贝。。
开发中,优先用 浅拷贝,性能更好;如果确实需要完全独立的数据,才考虑 深拷贝。
更多推荐


所有评论(0)