深拷贝(Deep Copy)和浅拷贝(Shallow Copy)都是复制对象的方法,但它们复制对象中的内容的深度不同。
浅拷贝(Shallow Copy):
{...obj})、Object.assign() 或数组的 .slice()、.concat() 等方法来实现。示例:
const original = {
name: "John",
pets: ["dog", "cat"]
};
const shallowCopy = { ...original };
shallowCopy.pets.push("parrot");
console.log(original.pets); // ["dog", "cat", "parrot"],原始对象受到影响
深拷贝(Deep Copy):
使用递归或特定的深拷贝函数来实现,因为它需要在复制过程中遍历整个对象的结构,确保每个引用类型数据都被复制。示例:
const original = {
name: "John",
pets: ["dog", "cat"]
};
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.pets.push("parrot");
console.log(original.pets); // ["dog", "cat"],原始对象不受影响
需要注意的是,深拷贝可能会更耗费计算资源和时间,特别是对于大型、嵌套深度较大的对象。选择深拷贝或浅拷贝取决于你的需求,如果需要确保新对象与原始对象完全独立,不共享引用类型数据,那么应该使用深拷贝。否则,如果共享引用类型数据不是问题,浅拷贝可能更高效。
递归复制:
使用递归函数遍历原始对象的属性和嵌套引用类型数据,并创建一个新的对象来存储复制后的数据。这是手动实现深拷贝的一种方式,适用于各种对象结构。
function deepCopy(obj) {
if (obj === null || typeof obj !== 'object') {
return obj; // 如果是原始值或 null,则直接返回
}
let copy = Array.isArray(obj) ? [] : {}; // 根据类型创建新对象或数组
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]); // 递归复制属性
}
}
return copy;
}
JSON 序列化与反序列化:
使用 JSON.stringify() 方法将原始对象转换为 JSON 字符串,然后再使用 JSON.parse() 方法将 JSON 字符串转换为新的对象。这种方法对于能够被 JSON 序列化的对象非常有效,但它会忽略特殊数据类型(如函数、undefined)。
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
第三方库:
有一些第三方 JavaScript 库(如 lodash 的 _.cloneDeep() 方法)专门用于实现深拷贝,它们提供了高效且全面的深拷贝解决方案。
const _ = require('lodash');
const deepCopy = _.cloneDeep;
自定义实现:
根据具体需求,可以自定义深拷贝函数,针对特殊数据类型或对象结构进行处理。这需要更多的编码工作,但可以满足特定需求。
实现深拷贝时需要考虑如何处理循环引用以避免无限递归。