{"ScriptPreparationCode":"const TestObject = {\r\n description:\r\n \u0022Creates a deep copy of source, which should be an object or an array.\u0022,\r\n myNumber: 123456789,\r\n myBoolean: true,\r\n jayson: {\r\n stringify:\r\n \u0022JSON.stringify() method converts a JavaScript value to a JSON string....\u0022,\r\n parse: \u0022JSON.parse() method parses a JSON string...\u0022,\r\n },\r\n}\r\nfunction testFn(arg1, arg2) {\r\n console.log({ arg1, arg2 })\r\n}\r\n\r\ntestFn.fn_one = function (arg3, arg4) {\r\n console.log({ thisArg: this, arg3, arg4 })\r\n}\r\ntestFn.str_val = \u0022String Value\u0022\r\ntestFn.bool_val = true\r\ntestFn.sym_val = Symbol.for(\u0022test\u0022)\r\ntestFn.obj_val = TestObject\r\n\r\nconst person = {\r\n name: \u0022John Doe\u0022,\r\n age: 34,\r\n address: {\r\n country: \u0022USA\u0022,\r\n city: \u0022Boston\u0022,\r\n },\r\n hobbies: [\u0022Reading\u0022, \u0022Cooking\u0022],\r\n active: true,\r\n signDate: new Date(),\r\n superPowers: new Set([\u0022strength\u0022, \u0022fly\u0022]),\r\n knowledge: new Map([\r\n [\u0022history\u0022, \u0022good\u0022],\r\n [\u0022math\u0022, \u0022bad\u0022],\r\n ]),\r\n testFn,\r\n}\r\n\r\nfunction isObject(value) {\r\n return typeof value == \u0022object\u0022 \u0026\u0026 value != null\r\n}\r\nfunction isFunction(value) {\r\n return typeof value == \u0022function\u0022\r\n}\r\n\r\nfunction assignFnResultForEachProperty(targetObj, srcObj, getPropValueFn) {\r\n const keys = Object.keys(srcObj)\r\n for (const k of keys) {\r\n if (isObject(srcObj[k]) || isFunction(srcObj[k])) {\r\n targetObj[k] = getPropValueFn(srcObj[k])\r\n }\r\n }\r\n return targetObj\r\n}\r\n\r\nfunction createFunctionWrapper (fn) {\r\n return function (...args) {\r\n return value.call(this, ...args)\r\n }\r\n}\r\n\r\n\r\nfunction tryStructuredClone (value) {\r\n if (isFunction(value)) {\r\n const result = createFunctionWrapper(value);\r\n const keys = Object.keys(value);\r\n for (const key of keys) {\r\n result[ key ] = tryStructuredClone(value[ key ]);\r\n }\r\n return result;\r\n }\r\n else if (!isObject(value)) {\r\n return value;\r\n }\r\n try {\r\n return structuredClone(value);\r\n }\r\n catch {\r\n const result = {};\r\n const keys = Object.keys(value);\r\n for (const key of keys) {\r\n result[ key ] = tryStructuredClone(value[key]);\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nfunction recursiveDeepCopy(value) {\r\n let result\r\n if (isObject(value)) {\r\n if (Array.isArray(value)) {\r\n result = []\r\n }\r\n result = {}\r\n } else if (isFunction(value)) {\r\n result = createFunctionWrapper(value);\r\n } else {\r\n // Primitive value\r\n return value\r\n }\r\n for (const key in value) {\r\n result[key] = recursiveDeepCopy(value[key])\r\n }\r\n return result\r\n}\r\n\r\nfunction recursiveSpreadClone(value) {\r\n if (isObject(value)) {\r\n if (Array.isArray(value)) {\r\n const result = [...value]\r\n const nonIdxProps = Object.keys(value).filter((k) =\u003E !/^\\d\u002B$/.test(k))\r\n const otherProps = Object.fromEntries(\r\n nonIdxProps.map((k) =\u003E [k, value[k]])\r\n )\r\n return assignFnResultForEachProperty(\r\n Object.assign(result, otherProps),\r\n value,\r\n recursiveSpreadClone\r\n )\r\n }\r\n return assignFnResultForEachProperty(\r\n { ...value },\r\n value,\r\n recursiveSpreadClone\r\n )\r\n }\r\n if (isFunction(value)) {\r\n const result = createFunctionWrapper(value);\r\n return assignFnResultForEachProperty(\r\n Object.assign(result, { ...value }),\r\n value,\r\n recursiveSpreadClone\r\n )\r\n }\r\n // Primitive value\r\n return value\r\n}\r\nfunction recursiveAssignClone(value) {\r\n if (isObject(value)) {\r\n if (Array.isArray(value)) {\r\n return assignFnResultForEachProperty(\r\n Object.assign([], value),\r\n value,\r\n recursiveAssignClone\r\n )\r\n }\r\n return assignFnResultForEachProperty(\r\n Object.assign({}, value),\r\n value,\r\n recursiveAssignClone\r\n )\r\n }\r\n if (isFunction(value)) {\r\n const result = createFunctionWrapper(value);\r\n return assignFnResultForEachProperty(\r\n Object.assign(result, { ...value }),\r\n value,\r\n recursiveAssignClone\r\n )\r\n }\r\n // Primitive value\r\n return value\r\n}\r\n\r\nvar myCopy = null\r\n\r\n\r\nfunction recursiveFromEntriesClone(value) {\r\n if (isObject(value)) {\r\n if (Array.isArray(value)) {\r\n const result = value.map(recursiveFromEntriesClone)\r\n const nonIdxProps = Object.keys(value).filter((k) =\u003E !/^\\d\u002B$/.test(k))\r\n const otherProps = Object.fromEntries(\r\n nonIdxProps.map((k) =\u003E [k, value[k]])\r\n )\r\n return assignFnResultForEachProperty(\r\n Object.assign(result, otherProps),\r\n otherProps,\r\n recursiveFromEntriesClone\r\n )\r\n }\r\n const result = Object.fromEntries(\r\n Object.keys(value).map((k) =\u003E [k, value[k]])\r\n )\r\n return assignFnResultForEachProperty(\r\n result,\r\n value,\r\n recursiveFromEntriesClone\r\n )\r\n }\r\n if (isFunction(value)) {\r\n const result = createFunctionWrapper(value);\r\n const otherProps = Object.fromEntries(\r\n Object.keys(value).map((k) =\u003E [k, value[k]])\r\n )\r\n return assignFnResultForEachProperty(\r\n Object.assign(result, otherProps),\r\n value,\r\n recursiveFromEntriesClone\r\n )\r\n }\r\n // Primitive value\r\n return value\r\n}\r\n\r\nfunction logResultsOfEach () {\r\n var lodash_res = _.cloneDeep(person);\r\n var deepCopy_res = recursiveDeepCopy(person)\r\n var spread_res = recursiveSpreadClone(person)\r\n var assign_res = recursiveAssignClone(person)\r\n var entries_res = recursiveFromEntriesClone(person)\r\n var structured_res = tryStructuredClone(person);\r\n \r\n var r = {\r\n lodash: lodash_res,\r\n deepCopy: deepCopy_res,\r\n spread: spread_res,\r\n assign: assign_res,\r\n entries: entries_res,\r\n structured: structured_res\r\n }\r\n console.log(r);\r\n}\r\nlogResultsOfEach();\r\n","TestCases":[{"Name":"Lodash cloneDeep","Code":"myCopy = _.cloneDeep(person);","IsDeferred":false},{"Name":"tryStructuredClone","Code":"myCopy = tryStructuredClone(person);","IsDeferred":false},{"Name":"recursiveDeepCopy","Code":"myCopy = recursiveDeepCopy(person);","IsDeferred":false},{"Name":"recursiveSpreadClone","Code":"myCopy = recursiveSpreadClone(person);","IsDeferred":false},{"Name":"recursiveAssignClone","Code":"myCopy = recursiveAssignClone(person);","IsDeferred":false},{"Name":"recursiveFromEntriesClone","Code":"myCopy = recursiveFromEntriesClone(person);","IsDeferred":false}]}