JS高级:深浅拷贝

浅拷贝:

概念: 浅拷贝只会拷贝栈中的内容,而不会拷贝堆中的内容。也就是说当拷贝的对象是基本数据类型的话利用浅拷贝就可以完成拷贝,并且不会影响原来的内容;如果是引用数据类型的话,浅拷贝只会拷贝内容的第一层内容,而无法拷贝更深层的对象内容,也就是对于深层对象拷贝的是引用地址。

方法:
(1)Object.assign({}, target)
(2)扩展运算符 …target
(3)数组对象可以使用:arr.concat()、arr.slice()
在这里插入图片描述
图中可以看出浅拷贝修改第一层数据name不会影响原来的对象,但是修改深层对象friends则会影响原来的对象。
在这里插入图片描述

深拷贝:

概念: 深拷贝是通过在堆内存中重新开辟了一块内存空间来存放拷贝的对象,因此拷贝对象与被拷贝对象之间不会相互影响。

方法:
(1)JSON.parse(JSON.stringfy(target))
注意:这种方法不会拷贝 undefined;不会拷贝Symbol对象;不会拷贝函数;不能解决循环引用的问题,会报错。

(2)自定义深拷贝函数:
具体处理逻辑如下图。
在这里插入图片描述
代码如下:

	function isObject(value) {
      const valueType = typeof value
      return (value !== null) && (valueType === "object" || valueType === "function")
    }

    function deepClone(originValue, map = new WeakMap()) {   // map 保存循环引用
       // 判断是否为Map类型
       if (originValue instanceof Map) {
        return new Map([...originValue])
      }

      // 判断是否为Set类型
      if (originValue instanceof Set) {
        return new Set([...originValue])
      }

      // 判断如果是Symbol的value 那么创建一个新的Symbol
      if (typeof originValue === "symbol") {
        return Symbol(originValue.description)
      }

      // 判断如果是函数那么直接使用同一个函数
      if (typeof originValue === "function") {
        return originValue
      }

      // 判断是否是对象 不是则直接返回原来的值
      if (!isObject(originValue)) {
        return originValue
      }
      
      // 判断是否存在Map对象
      if (map.has(originValue)) {
        return map.get(originValue)
      }

      const newObject = Array.isArray(originValue) ? [] : {}    // 判断是否为数组
      map.set(originValue, newObject)   // 设置Map对象 解决循环引用的问题
      for (key in originValue) {
        newObject[key] = deepClone(originValue[key], map)
      }

      // 对Symbol的key进行特殊的处理
      const symbolKeys = Object.getOwnPropertySymbols(originValue)
      for (const sKey of symbolKeys) {
        newObject[sKey] = deepClone(originValue[sKey], map)
      }
      return newObject
    }

测试代码:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值