浅拷贝 深拷贝

浅拷贝

1.   let clone  =   {...target }   用扩展运算符     targer = { xxxx: xxx }

2.

function clone(target) {
    let cloneTarget = {};
    for (const key in target) {
        cloneTarget[key] = target[key];
    }
    return cloneTarget;
};

深拷贝

function deepClone (target, map = new WeakMap()) { // 额外开辟一个存储空间WeakMap来存储当前对象
  if (target === null) return target      // 解决了null问题
  if (target instanceof Date) return new Date(target)  // 解决了 Date对象问题
  if (target instanceof RegExp) return new RegExp(target)    //解决了正则问题
  if(!(target instanceof Object) ) return target   //到这里,就剩下数组和对象还没解决。
  if (typeof target !== 'object') return target   // 如果是基本数据类型就返回

  const cloneTarget = new target.constructor() //解决了数组问题 此时,cloneTarget 为[] 或 {}
  if (map.get(target)) return map.get(target) // 当需要拷贝当前对象时,先去存储空间中找,如果有 
                                                 的话直接返回
  map.set(target, cloneTarget) // 如果存储空间中没有就存进 hash 里     解决了循环引用问题

  Reflect.ownKeys(target).forEach(key => {          // Reflect.ownKeys()解决了Symbol问题
    cloneTarget[key] = deepClone(target[key], map) // 递归拷贝每一层
  })
  return cloneTarget
}

参考:轻松拿下 JS 浅拷贝、深拷贝 - 掘金

如何背下来,这个深拷贝函数?

解决了 日期 正则 数组 Null Symbol 循环引用  

function deepClone (target,hash = new WeakMap()){

1.  先判断 时间 正则 和 null 如果是,返回它

2.  判断是不是对象(不是对象就剩普通属性了),如果不是,返回target

3. 这里要背 循环引用的两句,和中间插一句,用于解决 数组问题。

          3.1 如果hash里面target键值对有值,就返回target的值

          if (hash.get(target))return hash.get(target)

          3.2 返回一个对象或者数组

          let cloneTarget = new  target.constructor ()

          3.3  把cloneTarget 赋值给 hash里面的target键

4.  这里解决symbol问题,同时forEach遍历target对象,参数区域为 一个箭头函数,里面涉及到了 

        克隆对象 = deepClone( 当前对象  ,hash)

5.   返回克隆对象 cloneTarget

       

( key )=>{    cloneTarget [ key ]  = deepClone(  Target [ key ]  , hash    )                   }

JSON.sringify 和 JSON.parse  (深拷贝 )

JSON.parse(JSON.sringify(obj))

缺点: 不能正确拷贝 数组 日期 正则 函数等 (能拷贝数组)

.如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

Object . assign(obj)  常用于react 的 reducer 赋值

缺点:  能拷贝数组,但不能拷贝深层对象属性,属于是没用。

常见的 递归方式

module.exports = function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值