解决循环引用的深度克隆

解决循环引用的深度克隆

说明:

记录一下学习过程。对数组和对象进行深度克隆,对于其他类型的数据,则没有进行相应处理。比如:Symbol,Date, RegExp,其实也应该拷贝为一个新的对象返回----通过new的方式。而Function类型,则只需要返回一个新的函数FunA,这个函数FunA里再调用当前函数即可。

实现

/* 能解决循环引用的深度克隆: */
function DeepClone (obj, cach = new Set()) {
  const type = Object.prototype.toString.call(obj).slice(8, -1)
  if (cach.has(obj)) return obj
  cach.add(obj)

  if (type === 'Object' || type === 'Array')
  {
    let Cr = obj.constructor
    let newObj = new Cr()
    let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)]
    for (let i = 0; i < keys.length; i++) {
      newObj[keys[i]] = DeepClone(obj[keys[i]], cach);
    }
    return newObj
  } else {
    return obj;
  }
}

测试

const obj = {
  name: 'abc',
  age: 19,
  [Symbol('symbol')]: function (){console.log(this.name);},
  xxx: {
    name: 'zhangsan',
    age: 18,
  }
}
obj.xxx.boyfriend = obj

const newObj = DeepClone(obj)
console.log(obj.name === newObj.name);//true
console.log(obj.age === newObj.age);//true
console.log(obj[Object.getOwnPropertySymbols(obj)[0]] === newObj[Object.getOwnPropertySymbols(newObj)[0]]);//true
console.log(obj.xxx === newObj.xxx);//false <= 表明深度克隆成功
console.log(obj.xxx.boyfriend === newObj.xxx.boyfriend);//true <= 循环引用部分不能被克隆

总结

  1. 检测数据类型通用的方式:
const type = Object.prototype.toString.call(obj).slice(8, -1)
  1. 获得对象所有属性,包括Symbol类型:
let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值