Why JSON.parse(JSON.stringify) Fails for Deep Cloning and Better Alternatives

This article explains the hidden pitfalls of using JSON.parse(JSON.stringify) for deep cloning in JavaScript—such as circular references, loss of special types, prototype chain erosion, and broken collections—and introduces the native structuredClone API as a more reliable solution.

JavaScript
JavaScript
JavaScript
Why JSON.parse(JSON.stringify) Fails for Deep Cloning and Better Alternatives

In JavaScript development, deep cloning is a common need. Many developers use the one‑line solution JSON.parse(JSON.stringify(obj)), but this approach has many hidden problems.

Fatal flaws of JSON.stringify

The one‑liner looks simple but has serious limitations. It cannot handle the following cases:

1. Circular references

const obj = { name: "对象" };
obj.self = obj; // circular reference
// Throws TypeError: Converting circular structure to JSON
const copy = JSON.parse(JSON.stringify(obj));

If an object contains a circular reference, the method throws an error and crashes the program.

2. Loss of special data types

const original = {
  func: function() { console.log('函数'); },
  symbol: Symbol('符号'),
  undefined: undefined,
  date: new Date(),
  regexp: /正则/g,
  nan: NaN,
  infinity: Infinity,
};
const copy = JSON.parse(JSON.stringify(original));
console.log(copy);
// Output shows date turned into a string, RegExp becomes {}, NaN and Infinity become null,
// and func, Symbol, undefined are completely lost

JSON serialization cannot handle functions, Symbol, undefined; it converts Date to a string, RegExp to an empty object, and turns NaN/Infinity into null.

3. Prototype chain loss

class Person {
  constructor(name) { this.name = name; }
  sayHello() { return `你好,我是${this.name}`; }
}
const original = new Person('张三');
const copy = JSON.parse(JSON.stringify(original));
console.log(original.sayHello()); // "你好,我是张三"
console.log(copy.sayHello); // undefined – method lost
console.log(copy instanceof Person); // false – prototype lost

After deep cloning, the object becomes a plain object, losing all prototype methods and properties.

4. Map, Set, WeakMap, WeakSet handling

const original = {
  set: new Set([1, 2, 3]),
  map: new Map([['key', 'value']]),
};
const copy = JSON.parse(JSON.stringify(original));
console.log(copy); // { set: {}, map: {} } – data lost

These collection types turn into empty objects during JSON serialization, causing complete data loss.

More reliable deep‑clone alternatives

Because the JSON method has many pitfalls, modern browsers provide the native Structured Clone API structuredClone, which handles most cases:

// One‑line deep clone
const copy = structuredClone(original);

Advantages:

Supports circular references

Supports most built‑in types (Date, RegExp, Map, Set, etc.)

Performance is better than the JSON method

Disadvantages:

Does not support functions, DOM nodes, or custom prototype chains

Although JSON.parse(JSON.stringify(obj)) looks concise, its numerous defects can introduce unexpected bugs. The native structuredClone API is the recommended simple replacement for deep cloning in modern JavaScript.

frontendJavaScriptJSONdeep copystructuredClone
JavaScript
Written by

JavaScript

Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.