Introduction: Why Doesn't Regular Copying Work?
\n\nImagine: you are writing an application that processes a complex user configuration. You do const newConfig = oldConfig, change a couple of fields — and suddenly the original object also changes. Sound familiar? 👋
In JavaScript, objects are passed by reference. This means that a simple assignment operation does not create a new object, but only copies the pointer to the old one. This is where the main question that torments thousands of developers on Stack Overflow comes from: "What is the most efficient way to deep clone an object in JavaScript?".
\n\nIn this article, we will break down all the popular methods of deep copying, their pros, cons, and performance. You will learn which method to choose for 2024, and learn how to write your own reliable deep clone.
\n\nWhy Do We Even Talk About Deep Copying?
\n\nDeep copying (deep clone) creates a completely independent copy of an object with all nested structures. Unlike a shallow copy, where nested objects remain shared.
\n\nHere is a typical scenario when this is needed:
\n- \n
- Working with Redux / Zustand: you cannot mutate state, you need to create copies. \n
- Data serialization for sending to the server. \n
- Working with cache or configurations that cannot be changed. \n
- Unit tests: to not affect the original data. \n
But it's not that simple. If you try to copy an object with functions, undefined, Symbol, or circular references — many methods will fail or lose data. Let's analyze each method in detail.
Method 1: JSON.parse(JSON.stringify(obj)) — Old but Works
\n\nThis is the most popular method among beginners. It is simple and quick to write:
\n\nconst original = {\n name: "Anna",\n age: 25,\n address: { city: "Moscow", zip: 101000 },\n hobbies: ["reading", "running"]\n};\n\nconst clone = JSON.parse(JSON.stringify(original));\n\nclone.address.city = "Saint Petersburg";\nconsole.log(original.address.city); // "Moscow" — ✅ copy is independent!\n\n\nPros:
\n- \n
- 🔥 Very simple syntax. \n
- 🔥 Works for most simple cases. \n
Cons (critical!):
\n- \n
- ❌ Loses functions — they will turn into
undefined. \n - ❌ Loses undefined — fields with the value
undefinedwill disappear. \n - ❌ Loses Symbol — symbol keys will be lost. \n
- ❌ Does not work with circular references — will throw a
TypeError. \n - ❌ Problems with dates —
Datewill turn into a string. \n - ❌ Problems with Map, Set, RegExp — they will become empty objects. \n
Conclusion: Only suitable for data that is guaranteed to be serializable to JSON (strings, numbers, arrays, plain objects).
\n\nMethod 2: Structured Clone API — Modern Standard (2024)
\n\nStarting from 2022, JavaScript has a native way of deep copying — structuredClone. It is available in all modern browsers and Node.js 17+.
const clone = structuredClone(original);\n\nclone.address.city = "Kazan";\nconsole.log(original.address.city); // "Moscow" — ✅\n\n\nWhat structuredClone can do:
\n- \n
- ✅ Circular references — works! \n
- ✅ Dates — preserves the
Datetype. \n - ✅ Map and Set — copies correctly. \n
- ✅ RegExp — also works. \n
- ✅ ArrayBuffer and Ty