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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| function deepCopyAdvanced(source, map = new WeakMap()) { if (source === null || typeof source !== 'object') { return source; } if (map.has(source)) { return map.get(source); } switch (true) { case source instanceof Date: return new Date(source); case source instanceof RegExp: return new RegExp(source); case source instanceof Map: return new Map(Array.from(source, ([key, val]) => [deepCopyAdvanced(key, map), deepCopyAdvanced(val, map)] ); case source instanceof Set: return new Set(Array.from(source, item => deepCopyAdvanced(item, map)) ); case Array.isArray(source): const arrCopy = []; map.set(source, arrCopy); source.forEach((item, index) => { arrCopy[index] = deepCopyAdvanced(item, map); }); return arrCopy; default: const objCopy = Object.create( Object.getPrototypeOf(source) ); map.set(source, objCopy); const symbolKeys = Object.getOwnPropertySymbols(source); const allKeys = [...Object.keys(source), ...symbolKeys]; allKeys.forEach(key => { objCopy[key] = deepCopyAdvanced(source[key], map); }); return objCopy; } }
const original = { a: 1, b: { c: 2 }, d: new Date(), e: /regex/g, f: function() { return this.a; }, g: new Map([['key', 'value']]), h: new Set([1, 2, 3]), i: Symbol('unique'), j: [4, 5, { k: 6 }] };
original.self = original; original.j.push(original.j);
const copy = deepCopyAdvanced(original);
console.log(copy !== original); console.log(copy.b !== original.b); console.log(copy.d instanceof Date); console.log(copy.e instanceof RegExp); console.log(copy.f()); console.log(copy.g instanceof Map); console.log(copy.h instanceof Set); console.log(copy.i === original.i); console.log(copy.self === copy); console.log(copy.j[3] === copy.j);
|