JSON
JSON (JavaScript Object Notation) is a lightweight text format for structured data. It is the lingua franca of web APIs, configuration files, and inter-process communication — despite the name, it is language-independent.
JSON Syntax Rules
- Keys must be double-quoted strings
- Values: string, number, boolean,
null, array, or object - No trailing commas, comments, functions,
undefined,NaN, orInfinity - Strings use double quotes (single quotes are invalid in JSON)
{
"name": "Alice",
"age": 25,
"active": true,
"score": null,
"tags": ["js", "web"],
"address": {
"city": "New York",
"zip": "10001"
}
}
Valid JSON is a strict subset of JavaScript literal syntax — you cannot paste arbitrary JS into JSON.parse().
JSON.stringify — JavaScript to JSON
const user = {
name: 'Bob',
age: 30,
greet() { return 'hi'; }, // functions omitted
nickname: undefined // undefined values omitted
};
JSON.stringify(user);
// '{"name":"Bob","age":30}'
// Pretty print (indentation)
JSON.stringify(user, null, 2);
// Filter properties with replacer array
JSON.stringify(user, ['name']); // '{"name":"Bob"}'
// Replacer function
JSON.stringify(user, (key, value) => {
if (key === 'age') return undefined; // exclude age
return value;
});
Special Value Handling
JSON.stringify({ a: 1, b: undefined }); // '{"a":1}'
JSON.stringify({ a: NaN, b: Infinity }); // '{"a":null,"b":null}'
JSON.stringify({ a: new Date() }); // '{"a":"2024-06-13T..."}'
JSON.stringify([1, undefined, 3]); // '[1,null,3]' — array preserves null
JSON.parse — JSON to JavaScript
const json = '{"name":"Charlie","age":28}';
const obj = JSON.parse(json);
console.log(obj.name); // 'Charlie'
console.log(typeof obj); // 'object'
Reviver Function
Transform values during parsing:
const data = JSON.parse('{"date":"2024-06-13","amount":"99.50"}', (key, value) => {
if (key === 'date') return new Date(value);
if (key === 'amount') return parseFloat(value);
return value;
});
console.log(data.date instanceof Date); // true
console.log(typeof data.amount); // 'number'
Working with APIs
async function fetchUser(id) {
const response = await fetch(`https://api.example.com/users/${id}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json(); // internally calls JSON.parse
}
async function createUser(userData) {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
return response.json();
}
Always validate API responses — never assume the server returns valid JSON or expected shape.
Deep Clone (Simple Objects)
const original = { a: 1, b: { c: 2 }, tags: ['x'] };
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 99;
console.log(original.b.c); // 2 — deep copy
Limitations of JSON Clone
| Type | Result after parse/stringify |
|---|---|
Date |
ISO string (not Date object) |
Map, Set |
{} or [] (empty) |
undefined |
Omitted (objects) or null (arrays) |
| Functions | Omitted |
| Circular references | TypeError |
BigInt |
TypeError |
For robust cloning, use structuredClone() (modern browsers) or libraries like Lodash cloneDeep.
const clone = structuredClone(original); // handles Date, Map, circular refs
Schema Validation
Validate parsed JSON before use:
function parseUser(json) {
const data = JSON.parse(json);
if (typeof data.name !== 'string' || typeof data.age !== 'number') {
throw new TypeError('Invalid user schema');
}
return data;
}
For production APIs, use schema validators like Zod, Joi, or JSON Schema.
Common Errors
// SyntaxError — single quotes, unquoted keys, trailing comma
JSON.parse("{ name: 'Alice' }");
// SyntaxError — invalid token
JSON.parse('undefined');
// TypeError — circular reference
const obj = {};
obj.self = obj;
JSON.stringify(obj); // TypeError: Converting circular structure to JSON
Best Practices
- Always wrap
JSON.parsein try/catch when parsing untrusted input. - Validate parsed data against expected schema before use.
- Use
Content-Type: application/jsonheader for API requests. - Never eval JSON — use
JSON.parseexclusively. - Prefer
structuredCloneover JSON round-trip for deep copies. - Handle BigInt by converting to string before stringify if needed.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
SyntaxError: Unexpected token |
Invalid JSON syntax | Validate source; check quotes and commas |
| Missing properties after parse | undefined values stripped by stringify |
Use null as explicit empty marker |
| Dates become strings | JSON has no Date type | Use reviver or parse date fields manually |
| Large JSON freezes UI | Synchronous parse on main thread | Parse in Web Worker; paginate data |
| Unicode issues | Unescaped control characters | Ensure proper UTF-8 encoding |
JSON is essential for every web developer. Master stringify and parse, understand their limitations, and always validate external data before trusting it in your application.