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

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 solution.

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

In JavaScript development, deep cloning objects is a common need, and many developers resort to the one‑liner JSON.parse(JSON.stringify(obj)). While concise, this approach has serious limitations.

Critical flaws of JSON.stringify

The method cannot handle several scenarios:

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));

When an object contains a circular reference, JSON serialization throws an error, causing the program to crash.

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 as a string, RegExp as {}, NaN and Infinity as null, and func, symbol, undefined are completely lost

JSON cannot serialize functions, Symbols, or undefined; Date becomes a string; RegExp becomes an empty object; NaN and Infinity become 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

The cloned object becomes a plain object, losing all prototype methods and inheritance.

4. Handling of Map, Set, WeakMap, WeakSet

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: {} } – collections become empty objects

These collection types are serialized to empty objects, resulting in total data loss.

More reliable deep‑clone alternatives

Given these pitfalls, modern browsers provide the native structuredClone API, which can handle most cases:

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

Advantages:

Supports circular references

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

Better performance than the JSON method

Limitations:

Does not support functions, DOM nodes, or prototype chains

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

JavaScriptJSONprototypecircular referenceobject copyingstructuredClonedeep clone
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.