Why JSON.parse(JSON.stringify) Fails for Deep Copy and How structuredClone Fixes It

The article explains the hidden pitfalls of using JSON.parse(JSON.stringify(obj) for deep cloning in JavaScript—such as circular references, loss of special types, prototype chain, and collection handling—and introduces the native structuredClone API as a more reliable alternative.

JavaScript
JavaScript
JavaScript
Why JSON.parse(JSON.stringify) Fails for Deep Copy and How structuredClone Fixes It

In JavaScript development, deep cloning objects is a common need, but the one‑line shortcut JSON.parse(JSON.stringify(obj)) has many unexpected drawbacks.

Fatal flaws of JSON.stringify

Although it looks simple and elegant, this method cannot handle several important cases.

1. Cannot handle circular references

const obj = {
  name: "对象"
};
obj.self = obj; // 循环引用
// 抛出错误: TypeError: Converting circular structure to JSON
const copy = JSON.parse(JSON.stringify(obj));

If an object contains a circular reference, the operation 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:
// {
//   date: "2025-04-20T08:00:00.000Z", // turned into string
//   regexp: {}, // turned into empty object
//   nan: null, // turned into null
//   infinity: null // turned into null
//   // func, symbol and undefined are completely lost
// }

JSON serialization cannot preserve 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 chain lost

After cloning, the object becomes a plain object, losing all prototype methods and failing instanceof checks.

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: {} } - turned into empty objects

These collection types are serialized as empty objects, causing complete data loss.

More reliable deep copy alternatives

Because the JSON method has many pitfalls, modern browsers provide the native Structured Clone API structuredClone, which can handle most cases.

const copy = structuredClone(original);

Advantages:

Supports circular references

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

Performance better than the JSON method

Disadvantage:

Does not support functions, DOM nodes, or prototype chain

Although JSON.parse(JSON.stringify(obj)) looks concise, its numerous defects can introduce subtle bugs in real projects. 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.