递归实现深拷贝

94 阅读1分钟

思路

  1. 先判断是否为引用类型,基本类型不需要拷贝,直接返回
  2. 引用类型分为数组和对象,此方法不考虑函数
  • 如果为数组,则创建一个res=[],并使用forEach遍历;
  • 如果为对象,则创建一个res={},并使用for in遍历;
  • 总之:都是创建一个新的内存空间
  1. 赋值时应考虑当前项是否为引用类型,因此需要调再次用cloneDeep进行判断 39-4cloneDeep.svg
 function cloneDeep(target,cache = new Map()) {
        // 判断是否为引用类型object
        if (typeof target !== 'object') {
        //不是引用类型直接返回即可
          return target;
        }
        if(cache.has(target)){
        return cache
        }
        cache.set(target,result);
        //如果是引用类型,判断是数组还是对象,创建对应的堆内存空间
        let res = Array.isArray(target) ? [] : {};
        if (Array.isArray(target)) {
        //如果为数组,使用forEach遍历
          target.forEach(function (item, index) {
           //将遍历到的item值push到新数组中,有可能item也是引用类型,因此需要调用cloneDeep自己再进行判断
            res.push(cloneDeep(item));
          });
        } else {
        // 如果是对象,使用for in遍历
          for (var k in target) {
          // 将遍历到的属性值赋值给res对象中,target[k]可能也是引用类型,同上需要再次调用cloneDeep函数
            res[k] = cloneDeep(target[k]);
          }
        }
        // 返回 拷贝后的res
        return res;
      }