5

I have an object that contains circular references, and I would like to look at the JSON representation of it. For example, if I build this object:

var myObject = {member:{}};
myObject.member.child = {};
myObject.member.child.parent = myObject.member;

and try to call

JSON.stringify(myObject);

I get the error "too much recursion", not surprisingly. The "child" object has a reference to its "parent" and the parent has a reference to its child. The JSON representation does not have to be perfectly accurate, as I'm only using it for debugging, not for sending data to a server or serializing the object into a file or anything like that. Is there a way to tell JSON.stringify to just ignore certain properties (in this case the parent property of the child object), so that I would get:

{
    "member" : {
        "child" : {}
    }
}

The closest I can think of is to use getChild() and getParent() methods instead of just members, because JSON.stringify ignores any properties that are functions, but I'd rather not do that if I don't have to.

MatrixFrog
  • 20,873
  • 10
  • 56
  • 88
  • Both of the approaches that have been offered are still giving me "too much recursion" errors -- maybe there's some other weird dependency that I'm not seeing. – MatrixFrog Dec 08 '10 at 00:23

2 Answers2

8

You can pass a function as the second argument to stringify. This function receives as arguments the key and value of the member to stringify. If this function returns undefined, the member will be ignored.

alert(JSON.stringify(myObject, function(k, v) {
    return (k === 'member') ? undefined : v;
}));

...or use e.g. firebug or use the toSource()-method, if you only want to see whats inside the object.

alert(myObject.toSource());
CletusW
  • 3,392
  • 1
  • 21
  • 37
Dr.Molle
  • 113,505
  • 14
  • 184
  • 194
  • [`Object.toSource()`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/toSource) is a non-standard, Firefox-only feature. – Matt Ball Oct 09 '10 at 02:39
  • 5
    Object.toSource() was introduced in Javascript 1.3 and if it works in Firefox it's not a bad feature to "take a look" e.g. for debugging , whether its a part of ECMAScript or not. – Dr.Molle Oct 09 '10 at 02:56
6

From the crockford implementation (which follows the ECMA specification):

If the stringify method sees an object that contains a toJSON method, it calls that method, and stringifies the value returned. This allows an object to determine its own JSON representation.

Then something like this should work just fine:

var myObject =
{
    member: { child: {} }
}
myObject.member.child.parent = myObject.member;
myObject.member.child.toJSON = function ()
{
    return 'no more recursion for you.';
};

console.log(JSON.stringify(myObject));​

http://jsfiddle.net/feUtk/

Lucas
  • 11,997
  • 7
  • 62
  • 114
Matt Ball
  • 332,322
  • 92
  • 617
  • 683