Q9 of 40 · JavaScript

What does `JSON.stringify()` do, and what are its gotchas?

JavaScriptJuniorjavascriptjsonserializationapi-testingsnapshots

Short answer

Short answer: `JSON.stringify()` converts a JavaScript value to a JSON string. It silently drops `undefined`, functions, and Symbol-keyed properties. Circular references throw. The optional replacer and space arguments control field filtering and pretty-printing.

Detail

JSON.stringify(value, replacer, space) is the standard way to serialize JavaScript values for storage, HTTP request bodies, or snapshot comparisons in tests.

What it drops silently: Properties with undefined values are omitted. Functions and Symbol-keyed properties are also removed without warning. This can cause snapshot tests to pass even when the serialized form is incomplete.

Circular references: If an object contains a reference back to itself, JSON.stringify throws TypeError: Converting circular structure to JSON. Playwright traces and large page objects can hit this if you try to serialize them naively.

Replacer argument: Pass an array of string keys to include only those properties, or a function for custom logic — useful in test helpers to scrub timestamps or volatile IDs before comparing API snapshots.

Space argument: Pass a number (indent spaces) or string for pretty-printing. JSON.stringify(obj, null, 2) is the standard readable format.

JSON.parse: The inverse. Throws SyntaxError on invalid JSON — always wrap in try/catch when handling external input in test setups.

// EXAMPLE

const obj = {
  name: "test",
  fn: () => {},       // silently dropped
  val: undefined,     // silently dropped
  count: 0,
};

console.log(JSON.stringify(obj));
// '{"name":"test","count":0}'

// Pretty-print
console.log(JSON.stringify(obj, null, 2));
// {
//   "name": "test",
//   "count": 0
// }

// Replacer — keep only specific fields for API snapshot
const snapshot = JSON.stringify(obj, ["name", "count"]);
// '{"name":"test","count":0}'

// Round-trip clone (limited)
const clone = JSON.parse(JSON.stringify({ a: 1 }));

// WHAT INTERVIEWERS LOOK FOR

Awareness of what gets silently dropped and why that matters for assertions. The replacer pattern for scrubbing volatile fields in API snapshots is a sign of real-world testing experience.

// COMMON PITFALL

Using JSON.stringify for deep equality without knowing dropped fields — two objects that differ only in an `undefined` property compare as equal. Also: treating JSON round-trip as a reliable deep clone — it loses functions and `Date` objects become strings.