Update 2024: Sometimes you want to display a Javascript object as a string and when you use JSON.stringify you get an error: Converting circular structure to JSON. The solution is to use a function that keeps a record of objects found and returns a text explaining where the circular reference appeared.

Here is a function like that:

function fixCircularReferences(o) {

  const weirdTypes = [
    Int8Array,
    Uint8Array,
    Uint8ClampedArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    BigInt64Array,
    BigUint64Array,
    //Float16Array,
    Float32Array,
    Float64Array,
    ArrayBuffer,
    SharedArrayBuffer,
    DataView
  ];

  const defs=new Map();
  return (k,v) => {
    if (k && v==o) return '['+k+' is the same as original object]';
    if (v===undefined) return undefined;
    if (v===null) return null;
    const weirdType=weirdTypes.find(t=>v instanceof t);
    if (weirdType) return weirdType.toString();
    if (typeof(v) == 'function') {
      return v.toString();
    }
    if (v && typeof(v) == 'object') {
      const def = defs.get(v);
      if (def) return '['+k+' is the same as '+def+']';
      defs.set(v,k);
    }
    return v;
  }
}

And you use it like this:

const fixFunc = fixCircularReferences(someObject);
const json = JSON.stringify(someObject,fixFunc,2);

Possible improvements:

  • If you want to do more than just search through it, like actually deserialize it into something, you might not want to return the strings about "the same as" and return null instead.
  • If you want to serialize the circular references somehow, take a look at Newtonsoft's JSON PreserveReferencesHandling setting. You will need to also get the right id, not just the immediate property key name, which is more complicated.

Comments

Siderite

As far as I know an object reference is what is used as the "key" in the internal dictionary. It's never transformed to a string.

Siderite

???

this seems to use objects themselves as keys for def, which will not work for objects that do not return a unique string from toJSON...

???

John C

Lifesaver!! When using in (for example) Chrome's DevTools, usage is as simple as: > fx = function fixCircularReferences() { ...} <- undefined > JSON.stringify(object, fx(), 2) <- '{...}'

John C

Post a comment