Home/Learn/JavaScript & TypeScript/JSON — Serialising, Parsing and the Sharp Edges

JSON — Serialising, Parsing and the Sharp Edges

Beginner
Working with Data

JSON.stringify and JSON.parse move data between JavaScript and the wire. What they silently drop — undefined, functions, Dates, Map, Set — is the part worth knowing.

Overview

Every API call you make involves JSON in both directions, usually handled for you by fetch. Where it becomes your problem is when the round trip is not lossless: JSON has no date type, so Dates become strings and stay strings; undefined values disappear entirely; Map, Set and BigInt fail or vanish. Knowing the loss list is what stops the class of bug where data looks right until something downstream calls .getTime() on a string.

What Survives the Round Trip

JSON supports six types. Anything else is converted or dropped without warning.

The loss list
JSON.stringify({
  str: 'ok',           // survives
  num: 42,             // survives
  bool: true,          // survives
  nil: null,           // survives
  arr: [1, 2],         // survives
  obj: { a: 1 },       // survives

  undef: undefined,    // KEY REMOVED entirely
  fn: () => {},        // KEY REMOVED
  date: new Date(),    // becomes an ISO string, stays a string
  map: new Map([[1,2]]),  // becomes {} — contents lost
  set: new Set([1]),      // becomes {} — contents lost
  nan: NaN,            // becomes null
  inf: Infinity,       // becomes null
})
// BigInt throws: "Do not know how to serialize a BigInt"

// In an array, undefined becomes null rather than disappearing:
JSON.stringify([1, undefined, 3])     // '[1,null,3]'

Reviver and Replacer

Both functions take a hook that lets you fix types on the way through — the standard answer to the Date problem.

Fixing types on the way in and out
// Reviver — runs on every value while parsing
const ISO = /^\d{4}-\d{2}-\d{2}T/
const data = JSON.parse(text, (key, value) =>
  typeof value === 'string' && ISO.test(value) ? new Date(value) : value
)

// Replacer — runs on every value while serialising
JSON.stringify(obj, (key, value) =>
  key === 'password' ? undefined : value      // strip secrets
)

// Replacer as an allow-list of keys
JSON.stringify(user, ['id', 'name'])

// Third argument: indentation, for logs and files
JSON.stringify(obj, null, 2)

Parsing Safely

JSON.parse throws on malformed input, which will happen the first time a server returns an HTML error page with a 200.

Guarding parse, and a better deep clone
// Always guard — a proxy returning an HTML error page is common
function safeParse(text, fallback = null) {
  try { return JSON.parse(text) }
  catch { return fallback }
}

// With fetch, check the status before parsing
const res = await fetch(url)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const data = await res.json()      // throws if the body is not JSON

// Deep-cloning with JSON is a common trick, and lossy:
const bad = JSON.parse(JSON.stringify(obj))   // loses Dates, undefined, Map
const good = structuredClone(obj)             // keeps Dates, Map, Set

Key Points to Remember

  • 1JSON supports string, number, boolean, null, array and object — everything else is converted or dropped
  • 2undefined and functions are removed from objects entirely, but become null inside arrays
  • 3Dates become ISO strings and do not come back as Dates — use a reviver if you need them typed
  • 4JSON.parse throws on malformed input; check response.ok before parsing a fetch body
  • 5structuredClone() is a better deep clone than JSON round-tripping, which loses Dates, Map and Set

Interview Questions

Sign in to ask Aria
1

What happens to a Date object when you JSON.stringify and JSON.parse it?

Easy
2

Which values does JSON.stringify silently drop?

Medium
3

What is wrong with JSON.parse(JSON.stringify(obj)) as a deep clone?

Medium

Ask Aria about JSON — Serialising, Parsing and the Sharp Edges

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…