9-es5&es6深度拷贝

100 阅读1分钟

es5深度拷贝

// es5 的copy
var obj = {
  name: 'xr',
  age: 18,
  info: {
    hobby: ['travel', 'footerball'],
    carrer: {
      engineer: 5
    }
  }
}

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

  for (k in origin) {
    if(origin.hasOwnProperty(k)) {
      let item = origin[k];
      // 是对象
      if(typeof item === 'object' && item !== null) {
        tar[k] = toStr.call(item) === arrType ? [] : {};
        deepCloneByES5(item, tar[k]);
      } else {
        tar[k] = item;
      }
    }
  }

  return tar;
}

es6深度拷贝

  • 利用WeakMap避免内存的泄露

WeakMap基本使用

  const oBtn1 = document.querySelector('#btn1');
  const oBtn2 = document.querySelector('#btn2');

  const oBtnMap = new WeakMap();
  oBtnMap.set(oBtn1, handleBtn1Click);
  oBtnMap.set(oBtn2, handleBtn2Click);

  // 弱引用
  oBtn1.addEventListener('click', oBtnMap.get(oBtn1), false);
  oBtn2.addEventListener('click', oBtnMap.get(oBtn2), false);

  // oBtn1.addEventListener('click', handleBtn1Click, false);
  // oBtn2.addEventListener('click', handleBtn2Click, false);

  function handleBtn1Click() {}
  function handleBtn2Click() {}

  // 场景删掉节点,我们想把上面的方法销毁掉
  oBtn1.remove();
  oBtn2.remove();
  //=> 使用WeakMap删掉节点后会一并的垃圾回收上面的方法

  // es5理论需要这么做实际上我们可能不会这么做
  // handleBtn1Click = null;
  // handleBtn2Click = null;

深度拷贝

function deepCloneByWeakMap(origin, hashMap = new WeakMap()) {
  // 克隆的是基础值
  if (origin == undefined || typeof origin !== 'object') {
    return origin;
  }

  // Date类型
  if(origin instanceof Date) {
    return new Date(origin);
  }
  // 正则
  if (origin instanceof RegExp) {
    return new RegExp(origin);
  }

  const hashKey = hashMap.get(origin);
  if (hashKey) {
    return hashKey;
  }

  // 处理正常的对象数组(function一般不拷贝)
  // 产生一个新的 {} or []
  const target = new origin.constructor();

  hashMap.set(origin, target);
  for(let k in origin) {
    // 是否是私有属性
    if(origin.hasOwnProperty(k)) {
      target[k] = deepCloneByWeakMap(origin[key], hashMap);
    }
  }

  return target;
}

let test1 = {};
let test2 = {};

test2.test1 = test1;
test1.test2 = test2;

console.log(deepCloneByWeakMap(test2));//数据一直套娃