As developers, we’ve all faced the challenge of trying to deeply clone objects in JavaScript. Whether it’s duplicating a complex object or ensuring we don’t unintentionally mutate data, cloning is a common task.

For years, I stuck with the trusty JSON.stringify() + JSON.parse() combo. But as my projects grew, I realized that while this method worked most of the time, it wasn’t perfect. That’s when I discovered structuredClone(), a modern approach to deep cloning.

Let’s dive into why you might want to switch to structuredClone() and how it solves the problems that JSON.stringify() + JSON.parse() just can’t handle.

The Classic Approach: JSON.stringify() + JSON.parse()
For those who aren’t familiar with deep cloning, here’s the classic method

const clone = JSON.parse(JSON.stringify(myObject));

It works like a charm in many cases, especially when dealing with simple objects. But here’s the catch, this method fails when you run into certain data structures, and that's when structuredClone() comes to the rescue.

When Does JSON.stringify() + JSON.parse() Fall Short?
JSON.stringify() + JSON.parse() can be used for deep cloning simple objects, but it has limitations and doesn't handle all data types correctly. Here are some common limitations

1. Circular References
If your object has a circular reference (where an object refers to itself or another object that refers back to it), JSON.stringify() + JSON.parse() will throw an error.

Example:

const obj = { name: "Roja" };
obj.self = obj;  // Circular reference
const clone = JSON.parse(JSON.stringify(obj));  // Uncaught TypeError: Converting circular structure to JSON

2. Functions & Methods
If your object contains functions, they will be lost during cloning because JSON.stringify() + JSON.parse() only serializes data, not methods.

Example:

const obj = { name: "Roja", greet: () => "Hello!" };
const clone = JSON.parse(JSON.stringify(obj));
console.log(clone.greet);  // undefined

3. Dates
JSON.stringify() + JSON.parse() converts Date objects into strings, losing their functionality.

Example:

const obj = { date: new Date() };
const clone = JSON.parse(JSON.stringify(obj));
console.log(clone.date instanceof Date);  // false (it's now a string)

4. Complex Data Structures
If your object contains Map, Set, or Typed Arrays, they won’t be cloned properly.

Example:

const obj = { map: new Map([["key", "value"]]) };
const clone = JSON.parse(JSON.stringify(obj));
console.log(clone.map instanceof Map);  // false

Enter into structuredClone()

structuredClone() addresses the limitations of JSON.stringify() + JSON.parse(). It's a native function that can deeply clone objects, including complex data types, such as circular references, Map, Set, Dates, and more.

const clone = structuredClone(myObject);

Unlike JSON.stringify() + JSON.parse(), structuredClone() can handle

  • Circular references
  • Maps and Sets
  • Typed arrays and ArrayBuffers
  • Date objects

This method provides a much safer and more reliable way to clone complex objects.

When to Use structuredClone()?
If you're dealing with simple objects, JSON.stringify() + JSON.parse() might still be enough. But if your objects contain complex data structures, here’s when structuredClone() is the right choice:

1. Circular References
If you have an object with circular references, structuredClone() will clone it properly without throwing errors.

const obj = { name: "Roja" };
obj.self = obj;  // Circular reference
const clone = structuredClone(obj);
console.log(clone.self === clone);  // true

2. Maps and Sets
If your object includes Map or Set, structuredClone() will properly copy them, unlike JSON.stringify(), which can’t serialize them correctly.

const obj = { map: new Map([["key", "value"]]) };
const clone = structuredClone(obj);
console.log(clone.map instanceof Map);  // true

3. Typed Arrays & ArrayBuffers
structuredClone() can clone Typed Arrays and ArrayBuffers, which JSON.stringify() can’t handle.

const arr = new Uint8Array([1, 2, 3]);
const clone = structuredClone(arr);
console.log(clone instanceof Uint8Array);  // true

4. Dates
If you have Date objects, structuredClone() will preserve their Date functionality, unlike JSON.stringify() + JSON.parse() which converts them to strings.

const original = { date: new Date() };
const clone = structuredClone(original);
console.log(clone.date instanceof Date);  // true

So, When Should You Stick with JSON.stringify() + JSON.parse()?
If your objects are simple, and you don’t have the complex structures mentioned above, JSON.stringify() + JSON.parse() might still work just fine. Here’s a quick checklist:

  • Dates as strings (No need to preserve functionality)
  • Simple objects with no circular references
  • No Maps, Sets, or Typed Arrays

If this describes your use case, JSON.stringify() + JSON.parse() will likely suffice.

Conclusion

structuredClone() is the go to method when you need to deeply clone complex objects like those with circular references, Maps, Sets, Typed Arrays, or Dates.

If you're working with simple objects, JSON.stringify() + JSON.parse() is still a valid approach.

structuredClone() helps you avoid errors and issues that arise with JSON.stringify() + JSON.parse() and makes deep cloning much simpler.

Have You Used structuredClone() Yet?
I’m really excited about this method and plan to start using it in my future projects. Have you had any experience with it? How has it worked for you? Drop your thoughts below.