深拷贝

135 阅读1分钟

每天做个总结吧,坚持就是胜利!

    /**
        @date 2021-06-13
        @description 深拷贝
    */

壹(序)

浅拷贝与深拷贝:

在js中,拷贝引用数据类型时,如果此引用数据(假设为obj)中引用了另一个引用(假设为childObj),那么浅拷贝只会拷贝childObj引用地址,也就是说如果改变childObj里面的值,那么新的拷贝对象中的childObj也会改变;而深拷贝是将所有值都进行复制,即使是引用数据类型,也会重新声明一个新的对象,不会存在改变了原数据内的数据而影响拷贝数据的现象。

贰(代码实现)

// 判断是否是一个object
const isObject = (target) => {
  return typeof target === "object" && target !== null;
};

// 深拷贝
const cloneDeep = (target, hash = new WeakMap()) => {
  // 基本数据类型则直接返回
  if (!isObject(target)) {
    return target;
  }
  // 定义一个hashMap,如果hashMap中存在的话,直接返回,用来解决两个对象相互引用的情况
  if (hash.has(target)) {
    return hash.get(target);
  }
  // 定义拷贝后的对象
  const cloneTarget = Array.isArray(target) ? [] : {};
  // 向hashMap中插入值
  hash.set(target, cloneTarget);
  // 处理symbol情况
  const symKeys = Object.getOwnPropertySymbols(target);

  symKeys.forEach((item) => {
    const symTarget = target[item];

    if (isObject(symTarget)) {
      cloneTarget[item] = cloneDeep(symTarget, hash);
    } else {
      cloneTarget[item] = symTarget;
    }
  });
  // 非symbol
  const keys = Object.keys(target);

  keys.forEach((key) => {
    const objTarget = target[key];

    if (isObject(objTarget)) {
      cloneTarget[key] = cloneDeep(objTarget, hash);
    } else {
      cloneTarget[key] = objTarget;
    }
  });

  return cloneTarget;
};

// 测试
const childObj = { c: 3 };
const obj = { a: 1, b: 2, childObj };
obj.childObj = obj;

const sym = Symbol("test");
obj[sym] = 3;

console.log(obj); // {a: 1, b: 2, childObj: {…}, Symbol(test): 3}

const newObj = cloneDeep(obj);

console.log(newObj); // {a: 1, b: 2, childObj: {…}, Symbol(test): 3}

obj.a = 4;
obj[sym] = 5;

console.log(obj); // {a: 4, b: 2, childObj: {…}, Symbol(test): 5}
console.log(newObj); // {a: 1, b: 2, childObj: {…}, Symbol(test): 3}

const arr = [1, 2, {a: 3}];
const newArr = cloneDeep(arr);

console.log(arr); // [1 ,2 ,{a: 3}]
console.log(newArr); // [1 ,2 ,{a: 3}]

arr[0] = 4;
arr[2].a = 5;

console.log(arr); // [4 ,2 ,{a: 5}]
console.log(newArr); // [1 ,2 ,{a: 3}]

叁(结语欧)

大家端午安康!