JSON.stringify Deep Copy Limitations in JavaScript
Using JSON.parse(JSON.stringify(object)) is a popular
and quick hack for deep cloning objects in JavaScript. However, this
method relies strictly on the JSON standard rather than native
JavaScript data types, which leads to silent data corruption, lost data,
or runtime errors. This article outlines the major limitations of using
the JSON serialization approach for copying data structures in
JavaScript.
1. Functions and Methods Are Omitted
JSON does not support functions. If an object contains methods or
properties assigned to a function, JSON.stringify will
silently omit them from the resulting object. If a function is stored
inside an array, it will be converted into null.
const user = {
name: "Alice",
greet: () => console.log("Hello")
};
const copy = JSON.parse(JSON.stringify(user));
console.log(copy); // { name: "Alice" } (greet is missing)2. undefined
and Symbol Values Are Lost
Similar to functions, undefined values and
Symbol keys/values are not valid JSON. When stringified: *
Object properties with undefined or Symbol
values are omitted. * Symbol-keyed properties are completely ignored. *
Array elements containing undefined or Symbol
are converted to null.
3. Date Objects Are Converted to Strings
JSON does not have a native date type. When a JavaScript
Date object passes through JSON.stringify(),
its toISOString() method is called, converting the date to
a string. When parsed back via JSON.parse(), it remains a
string instead of being converted back into a Date
instance.
const event = { date: new Date() };
const copy = JSON.parse(JSON.stringify(event));
console.log(typeof copy.date); // "string", not an instance of Date4. Special Number Types Become
null
JavaScript values such as NaN, Infinity,
and -Infinity are not represented in the JSON standard.
JSON.stringify converts all of these values into
null.
const stats = { value: NaN, max: Infinity };
const copy = JSON.parse(JSON.stringify(stats));
console.log(copy); // { value: null, max: null }5. BigInt Throws a
TypeError
JSON.stringify cannot serialize BigInt
values by default. Attempting to copy an object that contains a
BigInt will throw an unhandled TypeError.
const data = { id: 100n };
JSON.stringify(data); // TypeError: Do not know how to serialize a BigInt6. Complex
Collections (Map, Set, RegExp)
Are Cleared
Data structures such as Map, Set, and
regular expressions (RegExp) are not recognized as
structured objects by JSON: * Map and Set are
serialized as empty objects ({}). * RegExp
instances are serialized as empty objects ({}). *
TypedArrays and Blobs also lose their internal binary
representations.
7. Circular References Crash Execution
If an object references itself directly or indirectly,
JSON.stringify cannot resolve the recursive structure and
will throw an error.
const obj = {};
obj.self = obj;
JSON.stringify(obj); // TypeError: Converting circular structure to JSON8. Prototype Chains Are Discarded
JSON only serializes enumerable, own properties. It does not preserve
the prototype chain. If you clone an instance of a custom class or
constructor function, the resulting copy will always be a plain
Object, losing all inherited properties and methods.
Better Alternatives
For modern JavaScript environments, consider these alternatives: *
structuredClone(): A built-in native API
that handles Date, RegExp, Map,
Set, BigInt, typed arrays, and circular
references. * Libraries like Lodash
(cloneDeep): Useful for older environments or when
custom cloning behavior is required.