JavaScript Easy technical 1 views 2 min read

What are the different ways to handle circular references in JSON?

Peer-reviewed by HireXTech Technical Panel Updated for 2025/2026 hiring Editorial standards
Practise this track
Interviewer Expectations for this Question
01
Core Competency

Assesses fundamental understanding of JavaScript conventions, runtime behavior, and memory/performance considerations.

02
Evaluation Criteria

Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.

Comprehensive Model Answer Verified Solution

Circular references occur when an object references itself directly or indirectly, causing JSON.stringify() to throw an error.

Problem:

     const obj = { name: 'John' };
     obj.self = obj; // Circular reference

     // JSON.stringify(obj); // Throws: TypeError: Converting circular structure to JSON
     

Solution 1: Custom replacer function:

     function stringifyWithCircular(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;
     console.log(stringifyWithCircular(obj));
     // {"name":"John","self":"[Circular]"}
     

Solution 2: flatted library (preserves structure):

     import { stringify, parse } from 'flatted';

     const obj = { name: 'John' };
     obj.self = obj;

     const serialized = stringify(obj);
     const deserialized = parse(serialized);
     console.log(deserialized.self === deserialized); // true
     

Solution 3: Manual tracking with paths:

     function safeStringify(obj, space) {
       const seen = new Map();
       let index = 0;

       return JSON.stringify(obj, function(key, value) {
         if (typeof value === 'object' && value !== null) {
           if (seen.has(value)) {
             return `[Circular:${seen.get(value)}]`;
           }
           seen.set(value, index++);
         }
         return value;
       }, space);
     }
     

Solution 4: Remove circular references:

     function removeCircular(obj) {
       const seen = new WeakSet();

       function detect(obj) {
         if (typeof obj === 'object' && obj !== null) {
           if (seen.has(obj)) {
             return undefined;
           }
           seen.add(obj);

           if (Array.isArray(obj)) {
             return obj.map(detect).filter(x => x !== undefined);
           }

           const cleaned = {};
           for (const [key, value] of Object.entries(obj)) {
             const cleaned value = detect(value);
             if (cleanedValue !== undefined) {
               cleaned[key] = cleanedValue;
             }
           }
           return cleaned;
         }
         return obj;
       }

       return detect(obj);
     }

     const obj = { name: 'John', child: { name: 'Jane' } };
     obj.child.parent = obj;
     const clean = removeCircular(obj);
     console.log(JSON.stringify(clean));
     

Solution 5: Using toJSON method:

     class Node {
       constructor(name) {
         this.name = name;
         this.parent = null;
         this.children = [];
       }

       toJSON() {
         return {
           name: this.name,
           children: this.children,
           // Exclude parent to avoid circular reference
         };
       }
     }

     const root = new Node('root');
     const child = new Node('child');
     root.children.push(child);
     child.parent = root;

     console.log(JSON.stringify(root)); // Works fine
     

Candidate Response Strategy & Interview Tips

  1. Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
  2. Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
  3. Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
  4. Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.
Related Topics & Skills
Spotted an error or have an alternative solution?