cloneDeep方案

问题:项目只用到lodash的cloneDeep,但其打包体积足有400k。方案:自己实现cloneDeep。

utils/index.js

export function cloneDeep(obj, hash = new WeakMap()) {
  // 基础类型和 null 直接返回
  if (obj === null || typeof obj !== 'object') return obj;

  // 查找缓存,防止循环引用导致无限递归
  const cachedClone = hash.get(obj);
  if (cachedClone) return cachedClone;

  let clone;
  // 处理 Array, Set, Map, Date, RegExp 等特殊类型
  switch (obj.constructor) {
    case Array:
      clone = [];
      break;
    case Object:
      clone = {};
      break;
    case Set:
      clone = new Set();
      break;
    case Map:
      clone = new Map(Array.from(obj));
      break;
    case Date:
      clone = new Date(obj);
      break;
    case RegExp:
      clone = new RegExp(obj.source, obj.flags);
      break;
    default:
      console.warn(
        `deepClone: Unsupported type encountered (${obj.constructor.name}).`
      );
      return undefined;
  }

  // 将复制的对象放入缓存
  hash.set(obj, clone);

  // 遍历并复制对象属性
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      clone[key] = cloneDeep(obj[key], hash);
    }
  }

  // 特殊处理 Set 和 Map 的值
  if (obj instanceof Set) {
    for (const value of obj) {
      clone.add(cloneDeep(value, hash));
    }
  } else if (obj instanceof Map) {
    for (const [key, value] of obj.entries()) {
      clone.set(key, cloneDeep(value, hash));
    }
  }

  return clone;
}

test:

var a = {
  a: 1,
  b: '11',
  c: false,
  d: [1, 'a'],
  e: { a: 1, b: { c: 2 } },
  f: new Date(),
  g: new Set([1, 'a']),
  h: new Map([[1, 'a']]),
  j: { say: () => 'hello' },
  k: a
};
var b = cloneDeep(a);
a.d.push(1);
console.log(a);
console.log(b);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值