最强最全深拷贝deepClone!!!

普通版本(可以处理循环引用):

function deepCopy(obj, hash = new WeakMap()) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  if (hash.has(obj)) {
    return hash.get(obj);
  }
  let copy;
  if (Array.isArray(obj)) {
    copy = [];
    hash.set(obj, copy);
    for (let i = 0; i < obj.length; i++) {
      copy[i] = deepCopy(obj[i], hash);
    }
  } else {
    copy = {};
    hash.set(obj, copy);
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        copy[key] = deepCopy(obj[key], hash);
      }
    }
  }
  return copy;
}

处理很多类型:

function deepClone(origin, target = {}, hash = new WeakMap()) {
   if (origin === null) return origin; // null || undefined
   else if (origin instanceof Date) return new Date(origin);
   else if (origin instanceof RegExp) return new RegExp(origin);
   else if (typeof origin !== 'object') return origin;

   // 解决引用闭环的问题
   if (hash.has(origin)) return hash.get(origin);
	// Reflect.ownKeys遍历自身所有属性
   Reflect.ownKeys(origin).forEach(function (key) {
     if (typeof origin[key] === 'object') {
       if (origin[key] instanceof Date)
         target[key] = new Date(origin[key]);
       else if (origin[key] instanceof RegExp)
         target[key] = new RegExp(origin[key]);
       else if (origin[key] instanceof Set)
         target[key] = new Set(origin[key]);
       else if (origin[key] instanceof Map)
         target[key] = new Map(origin[key]);
       else if (Object.prototype.toString.call(origin[key]) === '[object Array]') {
         target[key] = deepClone(origin[key], target[key], hash);
       }
       else if (Object.prototype.toString.call(origin[key]) === '[object Object]') {
         hash.set(origin, origin);
         target[key] = deepClone(origin[key], target[key], hash);
       } else {
         target[key] = null;
       }
     } else if (typeof origin[key] === 'function') {
       target[key] = new Function('return ' + origin[key].toString());
     }
     // 基本数据类型
     else {
       target[key] = origin[key];
     }
   });
   return target;
 }

测试代码

let s1 = Symbol('s1');

let obj = {
  a: '100',
  b: undefined,
  c: null,
  d: Symbol(2),
  e: /^\d+$/,
  f: new Date(),
  g: true,
  i: new Set([1, 2, 3, 4]),
  arr: [10, 20, 30],
  school: {
    name: 'cherry',
    [s1]: 's1'
  },
  fn: function fn() {
    console.log('fn');
  }
};

obj.h = obj;
let obj2 = deepClone2(obj);
console.log('obj', obj, 'obj2', obj2);

输出结果为
在这里插入图片描述
借鉴:文章1文章2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值