Working with JSON: stringify and parse
JSON.stringify() converts JavaScript data into a JSON string, and JSON.parse() converts a JSON string back into JavaScript data. This is one of the most frequently used pairs of methods in the language: it is needed everywhere data has to be stored or sent over the network.
Theory
TL;DR
JSON.stringify(value)is serialisation: an object or array becomes a string.JSON.parse(text)is deserialisation: a string becomes an object or array.stringifyskips functions,undefinedandSymbol, and walks nested objects recursively.- The third argument of
stringifysets the indentation:JSON.stringify(obj, null, 2). parsethrows aSyntaxErroron any invalid string, so it is usually wrapped intry/catch.JSON.parse(JSON.stringify(obj))is the popular trick for deep copying plain structures.
Quick example
const user = { name: 'Maria' };
const json = JSON.stringify(user); // '{"name":"Maria"}'
const obj = JSON.parse(json); // { name: 'Maria' }As a reminder, JSON is a text format for exchanging data, similar to JavaScript objects but meant for storage and transfer.
{
"name": "Maria",
"age": 25,
"isAdmin": false
}JSON.stringify(): object to string
The method converts a JavaScript object into a JSON formatted string.
const user = {
name: 'Maria',
age: 25,
isAdmin: false
};
const json = JSON.stringify(user);
console.log(json);
// '{"name":"Maria","age":25,"isAdmin":false}'
console.log(typeof json); // "string"Now json is an ordinary string that can be sent over the network or written to a file.
What JSON.stringify() actually does:
- turns an object or an array into a string;
- ignores functions,
undefinedand symbols (Symbol); - walks nested objects recursively.
An example with a function and undefined:
const data = {
name: 'JS',
greet() { console.log('Hi'); },
test: undefined
};
console.log(JSON.stringify(data));
// '{"name":"JS"}', functions and undefined do not make it into JSONInside an array such values do not disappear, they are replaced with null: JSON.stringify([1, undefined, () => {}]) gives '[1,null,null]'.
Formatting and the replacer
The result can be formatted nicely with indentation:
const json = JSON.stringify(user, null, 2);
console.log(json);
/*
{
"name": "Maria",
"age": 25,
"isAdmin": false
}
*/The second argument is the replacer, the third one is the number of spaces used for formatting. As a replacer you can pass an array of keys to keep, or a function that processes every key-value pair:
JSON.stringify(user, ['name']); // '{"name":"Maria"}'
JSON.stringify(user, (key, value) =>
key === 'age' ? undefined : value); // the age field is skippedIf an object has a toJSON() method, stringify calls it instead. That is why a Date is serialised into an ISO string.
JSON.parse(): string to object
The method converts a JSON string back into a JavaScript object.
const json = '{"name":"Maria","age":25,"isAdmin":false}';
const user = JSON.parse(json);
console.log(user.name); // "Maria"
console.log(user.age); // 25
console.log(typeof user); // "object"If the string is not valid, you get an error:
JSON.parse("{name:'Maria'}"); // SyntaxError: Unexpected token nThe correct version:
JSON.parse('{"name":"Maria"}');In JSON, keys and strings must always be in double quotes " ". Because of that, any JSON.parse() call on network data is worth wrapping in try/catch.
JSON.parse() has a second argument too, the reviver: a function that transforms every value while parsing, for example returning a Date instead of a string.
The two of them together
The methods are often used as a pair to persist data:
const user = { name: 'Maria', skills: ['JS', 'React'] };
const json = JSON.stringify(user);
localStorage.setItem('user', json); // the string is saved
const fromStorage = JSON.parse(localStorage.getItem('user'));
console.log(fromStorage.skills); // ['JS', 'React']This works precisely because localStorage can only store strings.
Deep copying an object
const obj = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(obj));
copy.b.c = 999;
console.log(obj.b.c); // 2, the original did not changeThis trick is often used to make a deep copy with no shared references. It only works for plain data; for everything else there is the built-in structuredClone(obj).
Summary table
| Method | Direction | What it does | Result |
|---|---|---|---|
JSON.stringify() | object to string | turns a JS object into JSON text | '{"name":"Maria"}' |
JSON.parse() | string to object | turns JSON text into a JS object | { name: 'Maria' } |
Common mistakes
- Calling
JSON.parse()withouttry/catch. An empty server response or HTML instead of JSON takes the application down with an exception. - Expecting every field to survive serialisation. Functions,
undefinedandSymbolvanish from an object and becomenullinside an array. - Using
JSON.parse(JSON.stringify(...))on complex structures. ADatebecomes a string,Map,SetandRegExpturn into empty objects, andBigIntthrows aTypeError. - Forgetting circular references. An object that points at itself gives
TypeError: Converting circular structure to JSON. - Hand-writing JSON with single quotes or a trailing comma. Such a string is valid JavaScript but invalid JSON.
- Assuming
JSON.stringify()guarantees a schema key order. The order comes from the object, so comparing two objects by comparing their JSON strings is unreliable.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.