Skip to content

深拷贝

两种深拷贝的实现

js
const obj = {
  name: 'xiaoyin',
  age: 24,
  career: '前端小菜鸡',
  info: {
    filed: ['JS', 'CSS', 'HTML'],
    framework: ['Vue', 'React', 'Angular'],
    student: [
      {
        name: 'xiaoyin',
        age: 24,
      },
      {
        name: 'xiaozhu',
        age: 20,
      },
    ],
  },
  hobby: ['跑步', '爬山'],
};

具体实现

js
function deepClone(origin, target) {
  var tar = target || {};
  var toStr = Object.prototype.toString;
  var arrayType = '[object Array]';

  if (typeof origin !== 'object' || origin === null) return origin;

  for (var key in origin) {
    if (origin.hasOwnProperty(key)) {
      if (typeof origin[key] === 'object' && origin[key] !== null) {
        tar[key] = toStr.call(origin[key]) === arrayType ? [] : {};
        deepClone(origin[key], tar[key]);
      } else {
        tar[key] = origin[key];
      }
    }
  }
  return tar;
}

const newObj = deepClone(obj);

console.log(newObj);
js
function deepClone(origin, hashMap = new WeakMap()) {
  // 此处写origin == undefined是因为==下undefined和null是相等的
  if (typeof origin !== 'object' || origin == undefined) return origin;

  if (origin instanceof Date) {
    return new Date(origin);
  }

  if (origin instanceof RegExp) {
    return new RegExp(origin);
  }

  const hasKey = hashMap.get(origin);

  if (hasKey) {
    return hasKey;
  }

  const target = new origin.constructor();
  hashMap.set(origin, target);
  for (let key in origin) {
    if (origin.hasOwnProperty(key)) {
      target[key] = deepClone(origin[key], hashMap);
    }
  }

  return target;
}

// const newObj = deepClone(obj);
// newObj.info.filed[0] = '卧槽';
// console.log(newObj,'newObj')
// console.log(obj)

//对象相互嵌套时候循环引用 若是直接传入此对象,会导致递归函数栈溢出 没有终止循环的条件
//所以采用WeakMap来解决这个问题 WeakMap是弱引用的Map并且其key可以是基本数据类型以外的其余类型
//因此此处可以使用WeakMap来存储已经访问过的对象,当再次访问到已经访问过的对象时,直接返回该对象即可,顺带终止了递归
// WeakMap只能以复杂数据类型作为key,并且key值是弱引用,对于垃圾回收更加友好。
let test1 = {};
let test2 = {};
test1.a = test2;
test2.b = test1;
console.log(deepClone(test1));

Keep Reading, Keep Writing, Keep Coding