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.
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 lostJSON 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 lostThe 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 objectsThese 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.
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.
