Js实现深拷贝

本文讲述了JavaScript中如何通过`deepClone`函数进行深拷贝,区分基本类型与引用类型的行为,以及在处理数组和对象时的递归策略。示例展示了深拷贝的特性:修改深拷贝对象不会影响原对象。
摘要由CSDN通过智能技术生成

尽管通过newObj = [...obj] 创建了一个新的数组,但是数组中的元素如果是基本类型,则新数组会拥有这些元素的独立副本;如果数组元素是引用类型,新数组则会复制这些引用(内存地址),而不是复制对象本身。所以仍需要对数组继续遍历递归。

const deepClone = (obj, hash = new WeakMap()) => {
  if (obj == null) return obj; //如果是null或者undefined直接返回,由于typeof null === "object",所以需要单独判断。
  if (typeof obj !== "object") return obj; //如果不是对象类型无需深拷贝,直接返回
  if (obj instanceof Date) return new Date(obj); //如果是Date类型,返回一个新的Date对象
  if (obj instanceof RegExp) return new RegExp(obj); //如果是RegExp类型,返回一个新的RegExp对象
  if (typeof obj === "function") return obj;
  let newObj = Object.create(null); //初始化新对象
  if (Array.isArray(obj)) {
    //如果obj是数组,则使用扩展运算符构造一个新数组。
    newObj = [...obj];
    hash.set(obj, newObj); //使用obj为键存入map中
    for (let i = 0; i < obj.length; i++) newObj[i] = deepClone(obj[i], hash); //然后递归遍历数组每一项,对每个元素深拷贝
    return newObj;
  }

  newObj = Object.create(Object.getPrototypeOf(obj)); //如果obj为对象类型,则创建一个继承obj原型链的新对象

  if (hash.get(obj)) return hash.get(obj); //如果map中已有拷贝完的对象,直接返回,无需重复深拷贝。
  hash.set(obj, newObj);
  for (const key of Object.keys(obj)) {
    //遍历obj的每一个键
    newObj[key] = deepClone(obj[key], hash); //对newObj的每一个值进行递归深拷贝
  }
  return newObj;
};

let bbb = [
  1,
  2,
  {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3],
  },
];
let b = deepClone(bbb);
b[0] = 2;
b[2]["a"] = 2;
console.log(b);
console.log(bbb);

   可以看到修改深拷贝的b对象并不影响原对象bbb。

  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值