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.
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 lostJSON 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 lostAfter 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 lostThese 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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
