JSON.stringify, avoid TypeError: Converting circular structure to JSON
I have a big object I want to convert to JSON and send. However it has circular structure. I want to toss whatever circular references exist and send whatever can be stringified. How do I do that?
Thanks.
var obj = {
a: "foo",
b: obj
}
I want to stringify obj into:
{"a":"foo"}
Use JSON.stringify
with a custom replacer. For example:
// Demo: Circular reference
var o = {};
o.o = o;
// Note: cache should not be re-used by repeated calls to JSON.stringify.
var cache = [];
JSON.stringify(o, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection
The replacer in this example is not 100% correct (depending on your definition of "duplicate"). In the following case, a value is discarded:
var a = {b:1}
var o = {};
o.one = a;
o.two = a;
// one and two point to the same object, but two is discarded:
JSON.stringify(o, ...);
But the concept stands: Use a custom replacer, and keep track of the parsed object values.
In Node.js, you can use util.inspect(object). It automatically replaces circular links with "[Circular]".
I really liked Trindaz's solution - more verbose, however it had some bugs. I fixed them for whoever likes it too.
Plus, I added a length limit on my cache objects.
If the object I am printing is really big - I mean infinitely big - I want to limit my algorithm.
JSON.stringifyOnce = function(obj, replacer, indent){
var printedObjects = [];
var printedObjectKeys = [];
function printOnceReplacer(key, value){
if ( printedObjects.length > 2000){ // browsers will not print more than 20K, I don't see the point to allow 2K.. algorithm will not be fast anyway if we have too many objects
return 'object too long';
}
var printedObjIndex = false;
printedObjects.forEach(function(obj, index){
if(obj===value){
printedObjIndex = index;
}
});
if ( key == ''){ //root element
printedObjects.push(obj);
printedObjectKeys.push("root");
return value;
}
else if(printedObjIndex+"" != "false" && typeof(value)=="object"){
if ( printedObjectKeys[printedObjIndex] == "root"){
return "(pointer to root)";
}else{
return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase() : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
}
}else{
var qualifiedKey = key || "(empty key)";
printedObjects.push(value);
printedObjectKeys.push(qualifiedKey);
if(replacer){
return replacer(key, value);
}else{
return value;
}
}
}
return JSON.stringify(obj, printOnceReplacer, indent);
};
链接地址: http://www.djcxy.com/p/48228.html