jiaochunxiao / fe-blog

好好学习,天天向上
1 stars 1 forks source link

模拟实现一个深拷贝,并考虑对象相互引用以及 Symbol 拷贝的情况 #4

Open jiaochunxiao opened 4 years ago

jiaochunxiao commented 4 years ago
function deepClone(target, cache = new Set()) {
  if (cache.has(target)) {
    return target;
  }
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  let res;
  if (target instanceof Array) {
    res = [];
    i = 0;
    j = target.length;
    target.map((item, index) => {
      cache.add(item)
      res[index] = deepClone(item, cache);
    })
  } else {
    if (Object.prototype.toString.call(target) === '[object Object]') {
      res = {};
      Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)).map(item => {
        cache.add(target[item]);
        res[item] = deepClone(target[item], cache);
      })
    }
  }
  return res;
}

注意点:

jiaochunxiao commented 4 years ago

如果是没有涉及到引用,function, Symbol这些较为复杂的对象。 较为简单的处理为:

const res = JSON.parse(JSON.stringify(target))

或者:

function deepClone(obj) {
  if (obj === null) return null; //null 的情况
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Date) return new Date(obj);
  if (typeof obj !== 'object') {
    //如果不是复杂数据类型,直接返回
    return obj;
  }
  /**
   * 如果obj是数组,那么 obj.constructor 是 [Function: Array]
   * 如果obj是对象,那么 obj.constructor 是 [Function: Object]
   */
  let t = new obj.constructor();
  for (let key in obj) {
    //如果 obj[key] 是复杂数据类型,递归
    t[key] = deepClone(obj[key]);
  }
  return t;
}

参考

jiaochunxiao commented 4 years ago

添加一篇博文:如何写出一个惊艳面试官的深拷贝?