JSON.parse and JSON.stringify are deceptively simple-looking functions with several non-obvious behaviors worth knowing before they surprise you in production.
const obj = { name: 'Widget', price: 9.99, created: new Date(), fn: () => {} };
JSON.stringify(obj);
// Dates become ISO strings, functions are silently DROPPED entirely:
// '{"name":"Widget","price":9.99,"created":"2025-09-08T..."}'
// Pretty-printing with indentation
JSON.stringify(obj, null, 2);
// A replacer function to filter or transform values during stringify
JSON.stringify(obj, (key, value) => key === 'price' ? undefined : value);
// A reviver function to transform values during parse
JSON.parse('{"date":"2025-09-08"}', (key, value) =>
key === 'date' ? new Date(value) : value
);
The Circular Reference Trap
const a = { name: 'a' };
a.self = a;
// JSON.stringify(a); // TypeError: Converting circular structure to JSON
Functions, undefined values, and symbols are silently dropped during stringify rather than causing an error — a common source of “why is this field missing from my API response” confusion.