💡

    Running Code Locally

    While this online editor runs real JavaScript, some advanced examples may have limitations. For the best experience: Download Node.js to run JavaScript on your computer, use your browser's Developer Console (Press F12) to test code snippets, or create a .html file with <script> tags and open it in your browser.

    Deep Dive into JSON, Parsing & Serialization

    Master JSON handling: serialization, parsing, type preservation, circular references, validation, and production patterns.

    What You'll Learn

    • JSON stringify & parse
    • Custom replacers & revivers
    • Handling circular references
    • Class serialization with type markers
    • Schema validation
    • JSON versioning & migrations

    📦 Real-World Analogy: Universal Shipping Label

    Think of JSON like a **universal shipping label**. When you send a package internationally, you need a label that everyone can read — regardless of what language they speak or what postal system they use. JSON is that universal label for data: it's a simple, text-based format that any programming language can read and write.

    📋 JSON Data Types Quick Reference:

    TypeJSON ExampleNotes
    String"hello"Must use double quotes
    Number42, 3.14No NaN or Infinity
    Booleantrue, falseLowercase only
    Nullnullundefined becomes null
    Array[1, 2, 3]Ordered list
    Object{"key": "value"}Keys must be strings

    What JSON Actually Is (And What It Cannot Represent)

    JSON (JavaScript Object Notation) is a text-based data format, not JavaScript itself. It has strict rules and can only represent: objects, arrays, strings, numbers, booleans, and null.

    JSON Cannot Represent

    • undefined - gets removed entirely
    • Functions - removed entirely
    • Dates - converted to ISO strings
    • NaN / Infinity - become null
    • RegExp, Map, Set - become empty objects
    • Circular references - throws error

    JSON Data Types

    What JSON can and cannot represent

    Try it Yourself »
    JavaScript
    // What JSON can represent
    const validData = {
      string: "Hello",
      number: 42,
      boolean: true,
      null: null,
      array: [1, 2, 3],
      object: { nested: "value" }
    };
    
    console.log(JSON.stringify(validData, null, 2));
    
    // What JSON CANNOT represent (these get lost or converted)
    const problematicData = {
      undefined: undefined,        // ❌ Removed entirely
      function: function() {},     // ❌ Removed entirely
      date: new Date(),            // ⚠️ Becomes ISO string
      nan: NaN,                    // ⚠️ 
    ...

    JSON.stringify — Serialization

    Serialization converts JavaScript values into JSON text. Understanding how different types are handled is crucial to avoiding data loss.

    JSON.stringify — Serialization

    Convert JavaScript values into JSON text

    Try it Yourself »
    JavaScript
    // Basic serialization
    const user = { name: "Boopie", age: 25 };
    const json = JSON.stringify(user);
    console.log(json);
    console.log(typeof json); // "string"
    
    // Pretty-printing with indentation
    console.log("\nPretty-printed:");
    console.log(JSON.stringify(user, null, 2));
    
    // Date conversion (becomes ISO string)
    const withDate = { created: new Date() };
    console.log("\nDate becomes string:");
    console.log(JSON.stringify(withDate));
    
    // NaN and Infinity become null
    const special = { nan: NaN, inf: I
    ...

    JSON.parse — Deserialization

    Parsing converts JSON text back to JavaScript values. JSON syntax is extremely strict — errors that JavaScript allows will crash JSON.parse.

    JSON.parse — Deserialization

    Convert JSON text back to JavaScript values

    Try it Yourself »
    JavaScript
    // Basic parsing
    const jsonText = '{"name":"Boopie","score":100}';
    const obj = JSON.parse(jsonText);
    console.log(obj.name);  // "Boopie"
    console.log(obj.score); // 100
    
    // STRICT syntax rules - these will FAIL:
    try {
      // Keys must be double-quoted
      JSON.parse("{name: 'value'}");
    } catch (e) {
      console.log("Error 1:", e.message);
    }
    
    try {
      // Strings must use double quotes, not single
      JSON.parse('{"name": \'value\'}');
    } catch (e) {
      console.log("Error 2:", e.message);
    }
    
    try {
      // No tra
    ...

    Custom Serialization with Replacers

    The replacer parameter in JSON.stringify lets you filter keys, transform values, mask sensitive data, and preserve type information.

    Custom Replacer Functions

    Filter keys, transform values, and mask sensitive data

    Try it Yourself »
    JavaScript
    // Replacer as array - filter specific keys only
    const user = {
      id: 1,
      name: "Boopie",
      password: "secret123",
      email: "boopie@test.com"
    };
    
    // Only include safe fields
    const safeJson = JSON.stringify(user, ["id", "name", "email"]);
    console.log("Filtered:", safeJson);
    
    // Replacer as function - transform values
    const data = {
      name: "Boopie",
      password: "secret123",
      createdAt: new Date(),
      balance: 1234.567
    };
    
    const transformed = JSON.stringify(data, (key, value) => {
      // Mask sensi
    ...

    Custom Parsing with Revivers

    The reviver parameter in JSON.parse lets you restore Dates, class instances, and other types that JSON destroys during serialization.

    Custom Reviver Functions

    Restore Dates, class instances, and other types

    Try it Yourself »
    JavaScript
    // Reviver function to restore types
    const jsonWithDate = '{"name":"Boopie","created":{"__type":"Date","value":"2025-01-15T10:30:00.000Z"}}';
    
    const restored = JSON.parse(jsonWithDate, (key, value) => {
      // Restore Date objects
      if (value && value.__type === "Date") {
        return new Date(value.value);
      }
      return value;
    });
    
    console.log("Name:", restored.name);
    console.log("Created type:", restored.created.constructor.name);
    console.log("Is Date?", restored.created instanceof Date);
    console.l
    ...

    Handling Circular References

    Circular references (objects referencing themselves) crash JSON.stringify. You need a custom serializer to handle them safely.

    Handling Circular References

    Safely serialize objects with circular references

    Try it Yourself »
    JavaScript
    // Circular references break JSON.stringify
    const obj = { name: "Parent" };
    obj.self = obj; // Circular!
    
    try {
      JSON.stringify(obj);
    } catch (e) {
      console.log("Error:", e.message);
    }
    
    // Safe stringify that handles circular references
    function safeStringify(obj, space = 2) {
      const seen = new WeakSet();
      
      return JSON.stringify(obj, (key, value) => {
        if (typeof value === "object" && value !== null) {
          if (seen.has(value)) {
            return "[Circular Reference]";
          }
          see
    ...

    Serializing Class Instances

    When you serialize class instances, all methods are lost. Here's how to preserve and restore class types through JSON.

    Serializing Class Instances

    Preserve and restore class types through JSON

    Try it Yourself »
    JavaScript
    // Classes lose their methods when serialized
    class User {
      constructor(name, role) {
        this.name = name;
        this.role = role;
      }
      
      greet() {
        return `Hello, I'm ${this.name}`;
      }
      
      isAdmin() {
        return this.role === "admin";
      }
    }
    
    const user = new User("Boopie", "admin");
    console.log("Before serialize:");
    console.log("greet():", user.greet());
    console.log("isAdmin():", user.isAdmin());
    
    // After JSON round-trip, methods are GONE
    const json = JSON.stringify(user);
    const parsed 
    ...

    JSON Schema Validation

    Never trust incoming JSON blindly. Always validate the structure, types, and required fields before using data in your application.

    JSON Schema Validation

    Validate structure, types, and required fields

    Try it Yourself »
    JavaScript
    // Manual schema validation (without external libraries)
    function validateUserSchema(data) {
      const errors = [];
      
      if (typeof data !== "object" || data === null) {
        return { valid: false, errors: ["Must be an object"] };
      }
      
      // Required fields
      if (typeof data.id !== "number") {
        errors.push("id must be a number");
      }
      if (typeof data.name !== "string" || data.name.length === 0) {
        errors.push("name must be a non-empty string");
      }
      if (typeof data.email !== "string" || !d
    ...

    JSON Transform Pipeline

    Professional applications use pipelines to process JSON: safe parse → validate → transform → normalize. This pattern keeps data handling consistent and safe.

    JSON Transform Pipeline

    Parse → validate → transform → normalize patterns

    Try it Yourself »
    JavaScript
    // Professional JSON processing pipeline
    class JSONPipeline {
      constructor() {
        this.transformers = [];
      }
      
      addTransformer(fn) {
        this.transformers.push(fn);
        return this; // chainable
      }
      
      process(json) {
        // Step 1: Safe parse
        let data;
        try {
          data = JSON.parse(json);
        } catch (e) {
          return { success: false, error: "Parse failed: " + e.message };
        }
        
        // Step 2: Run transformers
        try {
          for (const transform of this.transformers) {
      
    ...

    JSON Versioning & Migrations

    As your data schema evolves, you need a migration strategy to upgrade old JSON to new formats without breaking existing data.

    JSON Versioning & Migrations

    Upgrade old JSON formats without breaking data

    Try it Yourself »
    JavaScript
    // JSON versioning for backward compatibility
    const migrations = {
      // v1 -> v2: renamed 'username' to 'name'
      1: (data) => ({
        ...data,
        version: 2,
        name: data.username,
        username: undefined
      }),
      
      // v2 -> v3: nested profile object
      2: (data) => ({
        version: 3,
        profile: {
          name: data.name,
          email: data.email
        },
        settings: data.settings || {}
      })
    };
    
    function migrateToLatest(data) {
      const LATEST_VERSION = 3;
      let current = { ...data };
      
      // Def
    ...

    Safe JSON Storage (localStorage)

    Storing JSON in localStorage requires error handling, expiration support, and protection against corrupted data.

    Safe JSON Storage

    localStorage with error handling and expiration

    Try it Yourself »
    JavaScript
    // Safe localStorage with JSON
    const storage = {
      set(key, value, ttl = null) {
        const item = {
          value,
          timestamp: Date.now(),
          expires: ttl ? Date.now() + ttl : null
        };
        try {
          localStorage.setItem(key, JSON.stringify(item));
          return true;
        } catch (e) {
          console.error("Storage error:", e.message);
          return false;
        }
      },
      
      get(key) {
        try {
          const raw = localStorage.getItem(key);
          if (!raw) return null;
          
          const item
    ...

    Deep Cloning with JSON

    The JSON.parse(JSON.stringify(obj)) pattern creates deep clones, but has significant limitations. Know when to use it and when to use structuredClone.

    Deep Cloning with JSON

    Understand limitations of JSON cloning

    Try it Yourself »
    JavaScript
    // JSON cloning - simple but has limitations
    const original = {
      name: "Boopie",
      scores: [100, 95, 88],
      settings: { theme: "dark" }
    };
    
    // JSON clone method
    const jsonClone = JSON.parse(JSON.stringify(original));
    
    // Modify clone - original is safe
    jsonClone.scores.push(75);
    jsonClone.settings.theme = "light";
    
    console.log("Original scores:", original.scores);
    console.log("Clone scores:", jsonClone.scores);
    console.log("Original theme:", original.settings.theme);
    console.log("Clone theme:",
    ...

    JSON Best Practices

    ✅ DO

    • Always wrap parse in try/catch
    • Validate JSON structure before use
    • Use replacers to preserve type info
    • Use revivers to restore types
    • Handle circular references safely
    • Version your JSON schemas
    • Use UTF-8 encoding
    • Create transform pipelines

    ❌ DON'T

    • Use eval() to parse JSON
    • Assume API data is valid
    • Store Dates without restoration plan
    • Ignore type loss (undefined, functions)
    • Mutate parsed JSON directly
    • Use JSON for binary data
    • Skip schema validation
    • Ignore circular reference errors

    🎯 Mastery Summary

    • JSON is a strict text format — not all JS types survive serialization
    • JSON.stringify converts to text; JSON.parse converts back
    • Use replacers to filter/transform during serialization
    • Use revivers to restore types during parsing
    • Handle circular references with WeakSet tracking
    • Preserve class instances with type markers
    • Always validate incoming JSON before using it
    • Build transform pipelines for consistent processing
    • Version your schemas and create migrations
    • Use structuredClone instead of JSON for complex deep cloning

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service