zhengyiming
20 小时以前 0ca66ba6d5f5d5502211b9d9c7bff036ebd3f1aa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 * 深度拷贝函数,支持多种数据类型和循环引用
 * @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;
}