vue.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // @ts-nocheck
  2. /**
  3. * 深度克隆一个对象或数组
  4. * @param obj 要克隆的对象或数组
  5. * @returns 克隆后的对象或数组
  6. */
  7. export function cloneDeep<T>(obj: any): T {
  8. // 如果传入的对象为空,返回空
  9. if (obj === null) {
  10. return null as unknown as T;
  11. }
  12. // 如果传入的对象是 Set 类型,则将其转换为数组,并通过新的 Set 构造函数创建一个新的 Set 对象
  13. if (obj instanceof Set) {
  14. return new Set([...obj]) as unknown as T;
  15. }
  16. // 如果传入的对象是 Map 类型,则将其转换为数组,并通过新的 Map 构造函数创建一个新的 Map 对象
  17. if (obj instanceof Map) {
  18. return new Map([...obj]) as unknown as T;
  19. }
  20. // 如果传入的对象是 WeakMap 类型,则直接用传入的 WeakMap 对象进行赋值
  21. if (obj instanceof WeakMap) {
  22. let weakMap = new WeakMap();
  23. weakMap = obj;
  24. return weakMap as unknown as T;
  25. }
  26. // 如果传入的对象是 WeakSet 类型,则直接用传入的 WeakSet 对象进行赋值
  27. if (obj instanceof WeakSet) {
  28. let weakSet = new WeakSet();
  29. weakSet = obj;
  30. return weakSet as unknown as T;
  31. }
  32. // 如果传入的对象是 RegExp 类型,则通过新的 RegExp 构造函数创建一个新的 RegExp 对象
  33. if (obj instanceof RegExp) {
  34. return new RegExp(obj) as unknown as T;
  35. }
  36. // 如果传入的对象是 undefined 类型,则返回 undefined
  37. if (typeof obj === 'undefined') {
  38. return undefined as unknown as T;
  39. }
  40. // 如果传入的对象是数组,则递归调用 cloneDeep 函数对数组中的每个元素进行克隆
  41. if (Array.isArray(obj)) {
  42. return obj.map(cloneDeep) as unknown as T;
  43. }
  44. // 如果传入的对象是 Date 类型,则通过新的 Date 构造函数创建一个新的 Date 对象
  45. if (obj instanceof Date) {
  46. return new Date(obj.getTime()) as unknown as T;
  47. }
  48. // 如果传入的对象是普通对象,则使用递归调用 cloneDeep 函数对对象的每个属性进行克隆
  49. if (typeof obj === 'object') {
  50. const newObj: any = {};
  51. for (const [key, value] of Object.entries(obj)) {
  52. newObj[key] = cloneDeep(value);
  53. }
  54. const symbolKeys = Object.getOwnPropertySymbols(obj);
  55. for (const key of symbolKeys) {
  56. newObj[key] = cloneDeep(obj[key]);
  57. }
  58. return newObj;
  59. }
  60. // 如果传入的对象是基本数据类型(如字符串、数字等),则直接返回
  61. return obj;
  62. }
  63. // 示例使用
  64. // // 克隆一个对象
  65. // const obj = { name: 'John', age: 30 };
  66. // const clonedObj = cloneDeep(obj);
  67. // console.log(clonedObj); // 输出: { name: 'John', age: 30 }
  68. // console.log(clonedObj === obj); // 输出: false (副本与原对象是独立的)
  69. // // 克隆一个数组
  70. // const arr = [1, 2, 3];
  71. // const clonedArr = cloneDeep(arr);
  72. // console.log(clonedArr); // 输出: [1, 2, 3]
  73. // console.log(clonedArr === arr); // 输出: false (副本与原数组是独立的)
  74. // // 克隆一个包含嵌套对象的对象
  75. // const person = {
  76. // name: 'Alice',
  77. // age: 25,
  78. // address: {
  79. // city: 'New York',
  80. // country: 'USA',
  81. // },
  82. // };
  83. // const clonedPerson = cloneDeep(person);
  84. // console.log(clonedPerson); // 输出: { name: 'Alice', age: 25, address: { city: 'New York', country: 'USA' } }
  85. // console.log(clonedPerson === person); // 输出: false (副本与原对象是独立的)
  86. // console.log(clonedPerson.address === person.address); // 输出: false (嵌套对象的副本也是独立的)