Serializing object that contains cyclic object value
Use the second parameter of stringify
, the replacer function, to exclude already serialized objects:
var seen = [];
JSON.stringify(obj, function(key, val) {
if (val != null && typeof val == "object") {
if (seen.indexOf(val) >= 0) {
return;
}
seen.push(val);
}
return val;
});
http://jsfiddle.net/mH6cJ/38/
As correctly pointed out in other comments, this code removes every "seen" object, not only "recursive" ones.
For example, for:
a = {x:1};
obj = [a, a];
the result will be incorrect. If your structure is like this, you might want to use Crockford's decycle or this (simpler) function which just replaces recursive references with nulls:
function decycle(obj, stack = []) {
if (!obj || typeof obj !== 'object')
return obj;
if (stack.includes(obj))
return null;
let s = stack.concat([obj]);
return Array.isArray(obj)
? obj.map(x => decycle(x, s))
: Object.fromEntries(
Object.entries(obj)
.map(([k, v]) => [k, decycle(v, s)]));
}
//
let a = {b: [1, 2, 3]}
a.b.push(a);
console.log(JSON.stringify(decycle(a)))
This is kind of an alternate-answer, but since what a lot of people will come here for is debugging their circular objects and there's not really a great way to do that without pulling in a bunch of code, here goes.
One feature that's not as well-known as JSON.stringify()
is console.table()
. Simply call console.table(whatever);
, and it will log the variable in the console in tabular format, making it rather quite easy and convenient to peruse the variable's contents.