手写系列-深拷贝

83 阅读1分钟

在手写深拷贝之前,首先要弄懂值类型引用类型的区别,可以更好的理解为什么需要深拷贝。

值类型

  • undefinedtypeof instance === "undefined"
  • Booleantypeof instance === "boolean"
  • Numbertypeof instance === "number"
  • Stringtypeof instance === "string
  • BigInttypeof instance === "bigint"
  • Symbol :typeof instance === "symbol"
  • nulltypeof instance === "object"

引用类型

Objecttypeof instance === "object" 包括 new Object,new Array,new Map,new Set

区别

  • 值类型传递的是值,引用类型是地址
  • 因为值类型都是比较简单的,占用内存小,所以采用值传递

深拷贝VS浅拷贝

值类型引用类型
浅拷贝修改拷贝后的不会影响原先的修改拷贝后的影响原先的
深拷贝修改拷贝后的不会影响原先的修改拷贝后的不会影响原先的

浅拷贝

常见的有

  • ...扩展符
  • object.assign
  • array.slice 本文不实现浅拷贝

深拷贝

常见的有

  • JSON.parse/JSON.parse

实现深拷贝注意的点

  • 注意判断值类型和引用类型
  • 注意判断是数组还是对象
  • 使用递归(不用也行)

深拷贝代码

/**
 * 深拷贝
 * @param {Object} obj 
 */
function deepClone(obj = {}) {
  if (typeof obj !== 'object' || obj == null) return obj

  // 初始化结果集
  const result = Array.isArray(obj) ? [] : {}
  
  for (key in obj) {
    // 保证key是自己的,不是原型链的
    if (obj.hasOwnProperty(key)) {
      result[key] = deepClone(obj[key])
    }
  }
  return result
}

测试

const obj1 = {
  age: 20,
  name: 'xxx',
  arr: [1,2,3,4],
  address: {
    city: 'nanning'
  }
}

const obj2 = deepClone(obj1)
obj2.age = 21
console.log(obj2)
console.log(obj1)

image.png

可以看到每个属性都拷贝了过来,而且修改拷贝后的对象obj2,并不会影响原来的