手写深拷贝函数--解决循环引用问题

深拷贝

手写深拷贝函数:满足了基本类型的拷贝,函数,set,map,symbol等的拷贝。

// 深拷贝 基本类型变量 symbol,方法 都可以拷贝
function isObject(val) {
  const valType = typeof val;
  return val && (valType === "object" || valType === "function");
}
function deepCopy(originValue) {
  // 创建一个map 主要是为了解决循环引用
  const loopRef = new WeakMap();
  function _deepCopy(originValue) {
    // symbol作为值的时候 我们需要重新创建一个symbol对象 
    if (typeof originValue === "symbol") {
      return Symbol(originValue.description);
    }
    // 基本类型,以及函数类型 直接返回 函数是为了复用 不需要重新创建一个
    if (!isObject(originValue) || typeof originValue === "function") return originValue;
    // 是set 和 map
    if (Object.prototype.toString.call(originValue).slice(8, -1) === "Set") {
      const newSet = new Set();
      originValue.forEach(value => {
        newSet.add(_deepCopy(value));
      });
      return newSet;
    }
    if (originValue instanceof Map) {
      const newMap = new Map();
      originValue.forEach((value, key) => {
        newMap.set(key, _deepCopy(value));
      });
      return newMap;
    }
    // 如果当前的对象已经在loopRef循环引用map里面存在了,不需要再次创建新对象 直接取出来返回即可了
    if (loopRef.has(originValue)) return loopRef.get(originValue);
    // 是对象 数组
    const newObject = Array.isArray(originValue) ? [] : {};
    // 把对象添加到我们的循环引用map中
    loopRef.set(originValue, newObject);
    for (const key in originValue) { // symbol作为key的时候 不会遍历到
      newObject[key] = _deepCopy(originValue[key]);
    }
    // 拿到作为key的symbol
    const symbolKeys = Object.getOwnPropertySymbols(originValue);
    for (const key of symbolKeys) {
      newObject[key] = _deepCopy(key);
    }
    return newObject;
  }
  return _deepCopy(originValue);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤雨东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值