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.
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 lostAfter 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 objectsThese 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.
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.
