/**
|
* 深度拷贝函数,支持多种数据类型和循环引用
|
* @param target 需要拷贝的目标值
|
* @param map 用于处理循环引用的映射表(内部使用)
|
* @returns 拷贝后的新值
|
*/
|
export function deepClone<T>(target: T, map = new WeakMap<any, any>()): T {
|
// 基本类型直接返回(null 特殊处理)
|
if (target === null || typeof target !== 'object') {
|
return target;
|
}
|
|
// 处理循环引用
|
if (map.has(target)) {
|
return map.get(target);
|
}
|
|
let cloneResult: any;
|
const Constructor = target.constructor;
|
|
// 处理日期
|
if (target instanceof Date) {
|
//@ts-ignore
|
cloneResult = new Constructor(target) as Date;
|
map.set(target, cloneResult);
|
return cloneResult as unknown as T;
|
}
|
|
// 处理正则
|
if (target instanceof RegExp) {
|
//@ts-ignore
|
cloneResult = new Constructor(target.source, target.flags) as RegExp;
|
cloneResult.lastIndex = target.lastIndex; // 复制lastIndex属性
|
map.set(target, cloneResult);
|
return cloneResult as unknown as T;
|
}
|
|
// 处理数组和对象
|
//@ts-ignore
|
cloneResult = new Constructor() as T;
|
map.set(target, cloneResult); // 存储映射关系,防止循环引用
|
|
// 遍历对象属性(包括Symbol键)
|
Reflect.ownKeys(target).forEach((key) => {
|
// 只拷贝自身属性,不拷贝原型链上的属性
|
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
cloneResult[key] = deepClone((target as any)[key], map);
|
}
|
});
|
|
return cloneResult;
|
}
|