关于深拷贝和浅拷贝的一些事

时间:2022-05-05 19:56:21

首先在进行认识深拷贝和浅拷贝之前,我们需要了解到W3关于数据类型的区分

数据类型:

  • 基本类型:String/Number/Boolean/Null/undefined/Symbol/
    • 直接存储在栈中的数据
  • 引用类型:Object,Array等
    • 存储的时是对象在栈中的引用,真实的数据存放在堆内存里

接下来我们开始了解深拷贝和浅拷贝:

 ------*深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的

  • 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
    • 实现方式
      • Object.assign()--当Object只有一层时,该方法为深拷贝:因为如果属性为基本类型,拷贝的就是基本类型的值,如果属性是内存地址(引用类型),拷贝的就是内存地址,因此对象改变了地址的话就会影响另一个对象;
      • Array.prototype.concat()
      • Array.prototype.slice()
  • 浅拷贝另外创造一个一模一样的对象,新对象和旧对象不共享内存,修改新对象不会影响旧对象
    • 实现方式
      • JSON.parse(JSON.stringfy(......))
      • 当然,你也可以手动通过递归的方式去进行拷贝
         1 //定义检测数据类型的功能函数
         2 function checkedType (target) {
         3     return Object.prototype.toString.call(target).slice(8, -1)
         4 }
         5 //实现深度克隆---对象/数组
         6 function clone (target) {
         7     //判断拷贝的数据类型
         8     //初始化变量result 成为最终克隆的数据
         9     let result, targetType = checkedType(target)
        10     if (targetType === 'object') {
        11         result = {}
        12     } else if (targetType === 'Array') {
        13         result = []
        14     } else {
        15         return target
        16     }
        17     //遍历目标数据
        18     for (let i in target) {
        19         //获取遍历数据结构的每一项值。
        20         let value = target[i]
        21         //判断目标结构里的每一值是否存在对象/数组
        22         if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
        23             //对象/数组里嵌套了对象/数组
        24             //继续遍历获取到value值
        25             result[i] = clone(value)
        26         } else {
        27             //获取到value值是基本的数据类型或者是函数。
        28             result[i] = value;
        29         }
        30     }
        31     return result
        32 }