问题:项目只用到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);