返回

简单实现深拷贝,快速 get!

前端

引言

在软件开发中,数据拷贝是经常遇到的操作。浅拷贝只拷贝数据结构的外层,而深拷贝则会递归拷贝所有层级的数据。本文将深入浅出地讲解如何简单实现深拷贝,让你在日常开发中轻松应对各种数据拷贝场景。

基本概念

  • 浅拷贝: 仅拷贝数据结构的引用,即拷贝后两个变量指向同一块内存。
  • 深拷贝: 递归拷贝所有层级的数据,即拷贝后两个变量指向不同的内存块。

实现方式

1. 循环遍历拷贝

这种方式适用于简单的数据结构,如数组和对象。

// 拷贝数组
const arr1 = [1, 2, 3];
const arr2 = [];
for (let i = 0; i < arr1.length; i++) {
  arr2[i] = arr1[i];
}

// 拷贝对象
const obj1 = { name: 'John', age: 30 };
const obj2 = {};
for (const key in obj1) {
  obj2[key] = obj1[key];
}

2. JSON 序列化和反序列化

这种方式适用于任何类型的数据,但效率较低。

const data = { name: 'John', age: 30, arr: [1, 2, 3] };
const dataCopy = JSON.parse(JSON.stringify(data));

3. 利用扩展运算符

ES6 中的扩展运算符 (...) 可以实现浅拷贝。对于嵌套数据结构,需要递归使用。

// 浅拷贝
const arr1 = [1, 2, 3];
const arr2 = [...arr1];

// 深拷贝
const obj1 = { name: 'John', age: 30 };
const obj2 = { ...obj1, hobby: 'coding' };

注意事项

  • 考虑特殊类型,如函数、正则表达式、日期等,需要特殊处理。
  • 避免循环引用,即对象中包含对自己的引用。

代码示例

// 深拷贝函数
function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
}

// 测试
const obj1 = { name: 'John', age: 30, arr: [1, 2, 3], func: function() { console.log('hello'); } };
const obj2 = deepCopy(obj1);

obj2.name = 'Mary';
obj2.arr[0] = 4;
obj2.func();  // 输出 'hello'

console.log(obj1, obj2);

结语

通过本文的讲解,相信你已经掌握了深拷贝的基本原理和实现方式。在实际开发中,根据具体场景选择合适的方法,可以有效提升代码效率和可靠性。如果你对深拷贝有更深入的需求,欢迎进一步探讨和交流。