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, or Infinity
  • 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.parse in try/catch when parsing untrusted input.
  • Validate parsed data against expected schema before use.
  • Use Content-Type: application/json header for API requests.
  • Never eval JSON — use JSON.parse exclusively.
  • Prefer structuredClone over 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.