JSON.parse and JSON.stringify in JavaScript
What is JSON?
JSON (JavaScript Object Notation) — a text format for data exchange based on JavaScript syntax.
JavaScript provides two main methods for working with JSON:
JSON.stringify()— convert object to JSON string (serialization)JSON.parse()— convert JSON string to object (deserialization)
JSON.stringify()
Converts JavaScript value to JSON string.
Basic Syntax
JSON.stringify(value, replacer, space)
Parameters
value— value to convertreplacer(optional) — function or array for filtering propertiesspace(optional) — number of spaces for formatting
Simple Examples
const user = {
name: 'John',
age: 25,
isActive: true
};
JSON.stringify(user);
// '{"name":"John","age":25,"isActive":true}'
// With formatting
JSON.stringify(user, null, 2);
/*
{
"name": "John",
"age": 25,
"isActive": true
}
*/
What Can Be Serialized?
Supported Types
// Objects
JSON.stringify({ a: 1 }); // '{"a":1}'
// Arrays
JSON.stringify([1, 2, 3]); // '[1,2,3]'
// Strings
JSON.stringify('text'); // '"text"'
// Numbers
JSON.stringify(42); // '42'
// Boolean
JSON.stringify(true); // 'true'
// null
JSON.stringify(null); // 'null'
What Gets Ignored or Converted
const obj = {
fn: function() {}, // Function - ignored
undef: undefined, // undefined - ignored
sym: Symbol('id'), // Symbol - ignored
date: new Date(), // Date → string
nan: NaN, // NaN → null
infinity: Infinity, // Infinity → null
regex: /test/, // RegExp → {}
map: new Map([[1, 'one']]), // Map → {}
set: new Set([1, 2, 3]) // Set → {}
};
JSON.stringify(obj);
// '{"date":"2024-01-01T00:00:00.000Z","nan":null,"infinity":null,"regex":{},"map":{},"set":{}}'
Important:
undefined, functions, and symbols:
- In objects — ignored
- In arrays — become
null
JSON.stringify([1, undefined, function() {}, 3]);
// '[1,null,null,3]'
replacer Parameter
Array (property filtering)
const user = {
name: 'John',
age: 25,
password: 'secret123',
email: 'john@example.com'
};
// Serialize only name and email
JSON.stringify(user, ['name', 'email']);
// '{"name":"John","email":"john@example.com"}'
Function (value transformation)
const obj = {
name: 'John',
age: 25,
salary: 100000
};
JSON.stringify(obj, (key, value) => {
// Hide salary
if (key === 'salary') return undefined;
// Double age
if (key === 'age') return value * 2;
return value;
});
// '{"name":"John","age":50}'
replacer Function Parameters
key— property key (empty string for root object)value— property valuethis— parent object
const data = { a: 1, nested: { b: 2 } };
JSON.stringify(data, function(key, value) {
console.log(`key: "${key}", value:`, value);
return value;
});
// key: "", value: { a: 1, nested: { b: 2 } } ← root object
// key: "a", value: 1
// key: "nested", value: { b: 2 }
// key: "b", value: 2
space Parameter (formatting)
const obj = { name: 'John', age: 25 };
// Number - number of spaces
JSON.stringify(obj, null, 2);
/*
{
"name": "John",
"age": 25
}
*/
// String - prefix for each level
JSON.stringify(obj, null, '→ ');
/*
{
→ "name": "John",
→ "age": 25
}
*/
toJSON() Method
Objects can define custom serialization behavior through toJSON() method.
const user = {
name: 'John',
birthDate: new Date(1998, 5, 15),
toJSON() {
return {
name: this.name,
age: new Date().getFullYear() - this.birthDate.getFullYear()
};
}
};
JSON.stringify(user);
// '{"name":"John","age":26}'
Built-in toJSON in Date
const date = new Date();
date.toJSON(); // "2024-01-15T12:00:00.000Z"
JSON.stringify({ created: date });
// '{"created":"2024-01-15T12:00:00.000Z"}'
Circular References
const obj = { name: 'John' };
obj.self = obj; // Circular reference
try {
JSON.stringify(obj);
} catch (error) {
console.error(error);
// TypeError: Converting circular structure to JSON
}
Solution: Use WeakSet
function stringifyWithoutCircular(obj) {
const seen = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return '[Circular]';
}
seen.add(value);
}
return value;
});
}
const obj = { name: 'John' };
obj.self = obj;
stringifyWithoutCircular(obj);
// '{"name":"John","self":"[Circular]"}'
JSON.parse()
Converts JSON string to JavaScript value.
Basic Syntax
JSON.parse(text, reviver)
Parameters
text— JSON string to parsereviver(optional) — value transformation function
Examples
JSON.parse('{"name":"John","age":25}');
// { name: 'John', age: 25 }
JSON.parse('[1, 2, 3]');
// [1, 2, 3]
JSON.parse('true'); // true
JSON.parse('null'); // null
JSON.parse('"text"'); // "text"
JSON.parse('42'); // 42
reviver Parameter
Function for transforming values during parsing.
const json = '{"name":"John","birthDate":"1998-06-15T00:00:00.000Z"}';
const user = JSON.parse(json, (key, value) => {
if (key === 'birthDate') {
return new Date(value); // Convert string to Date
}
return value;
});
console.log(user.birthDate instanceof Date); // true
reviver Function Parameters
key— property keyvalue— property valuethis— parent object
Function is called bottom-up (from nested to root).
const json = '{"a":1,"nested":{"b":2}}';
JSON.parse(json, (key, value) => {
console.log(`key: "${key}", value:`, value);
return value;
});
// key: "a", value: 1
// key: "b", value: 2
// key: "nested", value: { b: 2 }
// key: "", value: { a: 1, nested: { b: 2 } } ← last
Parsing Errors
// Syntax error
try {
JSON.parse("{name: 'John'}"); // Keys must be quoted
} catch (error) {
console.error(error);
// SyntaxError: Unexpected token n in JSON at position 1
}
// Unclosed string
JSON.parse('{"name": "John}'); // SyntaxError
// Trailing comma
JSON.parse('{"a": 1,}'); // SyntaxError
// Valid JSON
JSON.parse('{"name":"John"}'); // OK
JSON is Stricter Than JavaScript:
- Keys must be in double quotes
- Cannot use trailing commas
- Only double quotes for strings
- No comments
Deep Clone with JSON
Simple Cloning Method
const original = {
name: 'John',
address: {
city: 'New York'
}
};
const clone = JSON.parse(JSON.stringify(original));
clone.address.city = 'Boston';
console.log(original.address.city); // 'New York'
console.log(clone.address.city); // 'Boston'
Method Limitations
const obj = {
date: new Date(),
fn: () => {},
undef: undefined,
map: new Map([[1, 'one']]),
set: new Set([1, 2])
};
const clone = JSON.parse(JSON.stringify(obj));
console.log(clone);
// { date: '2024-01-15T12:00:00.000Z' } ← Date became string
// fn, undef, map, set — lost
Proper Deep Clone
For full cloning, use structuredClone() (modern standard):
const original = {
date: new Date(),
map: new Map([[1, 'one']]),
set: new Set([1, 2])
};
const clone = structuredClone(original);
console.log(clone.date instanceof Date); // true
console.log(clone.map instanceof Map); // true
Practical Examples
LocalStorage
// Saving
const user = { name: 'John', settings: { theme: 'dark' } };
localStorage.setItem('user', JSON.stringify(user));
// Loading
const loadedUser = JSON.parse(localStorage.getItem('user'));
API Requests
fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'John', age: 25 })
})
.then(response => response.json())
.then(data => console.log(data));
Object Comparison
function deepEqual(obj1, obj2) {
return JSON.stringify(obj1) === JSON.stringify(obj2);
}
deepEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // true
deepEqual({ a: 1, b: 2 }, { b: 2, a: 1 }); // false (key order matters)
Caution:
This method works only for simple objects and depends on key order.
Performance
const bigObject = { /* 10000 properties */ };
console.time('stringify');
const json = JSON.stringify(bigObject);
console.timeEnd('stringify'); // ~10ms
console.time('parse');
JSON.parse(json);
console.timeEnd('parse'); // ~5ms
JSON.parse()is usually faster thanJSON.stringify()- Can be slow for large objects
- Consider streaming parsers for huge JSON
Conclusion
JSON.stringify():
- Serializes objects, arrays, primitives
- Ignores functions, undefined, Symbol
- Supports
replacerfor filtering and transformation - Supports
spacefor formatting - Can be customized via
toJSON() - Doesn't work with circular references
JSON.parse():
- Parses valid JSON
- Supports
reviverfor transformation - Stricter than JavaScript (quotes, trailing commas)
- Can throw
SyntaxError
Deep Clone via JSON:
- Simple method
- Loses functions, Date, Map, Set
- Use
structuredClone()for full cloning
In Interviews:
Common questions:
- What gets lost with
JSON.stringify()? - How to handle circular references?
- What's the difference between
JSON.parse()andeval()? - How to make a deep clone?
- What are
replacerandreviverfor?