JavaScript 中的浅复制与深复制
概述
在 JavaScript 中,复制对象或数组可分为浅复制和深复制。处理复杂数据结构(尤其是包含嵌套对象或数组的数据结构)时,了解两者的区别至关重要。
本指南解释了这些概念、它们的特征、实现方法以及何时使用它们。
1.浅拷贝
**定义**
浅拷贝会创建对象或数组顶层属性的副本。但是,对于嵌套对象或数组,只会复制引用,而不会复制实际数据。
**特征**
**1.1 使用 Object.assign()**
const original = { a: 1, b: { c: 2 } }; const shallowCopy = Object.assign({}, original); shallowCopy.b.c = 42; console.log(original.b.c); // OUTPUT: 42 (The original object also affected due to shared reference)
**1.2 使用展开运算符 (...)**
const original = { a: 1, b: { c: 2 } }; const shallowCopy = { ...original }; shallowCopy.b.c = 90; console.log(original.b.c); // OUTPUT: 90
**1.3 让我们看一个数组方法(slice、concat)浅拷贝的例子**
const original = [1, 2, [3, 4]]; const shallowCopy = original.slice(); shallowCopy[2][0] = 10; console.log(original[2][0]); // OUTPUT: 10
2.深层复制
**定义**
深层复制会创建对象或数组的完全独立副本。所有层级(包括嵌套结构)均会递归复制。对复制结构的更改不会影响原始结构,反之亦然。
**特征**
**2.1 使用 JSON.stringify() 和 JSON.parse()**
const original = { a: 1, b: { c: 2 } }; const deepCopy = JSON.parse(JSON.stringify(original)); deepCopy.b.c = 42; console.log(original.b.c); // OUTPUT: 2 (original remains unaffected)
**2.2 使用structuredClone()**
一种支持循环引用和特殊对象(如日期)的深度复制的现代方法。
const original = { a: 1, b: { c: 2 }, date: new Date() }; const deepCopy = structuredClone(original); deepCopy.b.c = 42; console.log(original.b.c); // OUTPUT: 2 console.log(original.date === deepCopy.date); // FALSE
**2.3 使用自定义递归函数**
一种手动处理复杂案例的灵活解决方案。
function deepCopy(obj) { if (obj === null || typeof obj !== "object") return obj; if (Array.isArray(obj)) return obj.map(deepCopy); const copy = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { copy[key] = deepCopy(obj[key]); } } return copy; } const original = { a: 1, b: { c: 2 } }; const deepCopyObj = deepCopy(original); deepCopyObj.b.c = 42; console.log(original.b.c); // OUTPUT: 2
3. 何时使用?
**浅拷贝**
**深层复制**
4. 总结
**浅拷贝**
**深层复制**
这是对 JavaScript 中对象的浅拷贝和深拷贝的深入解释。请根据您的用例和性能要求选择适当的方法。