4
function MyClass() {
    this.foo = "foo";
    this.bar = "bar";
}

MyClass.prototype.toJSON = function(space) {
    if (typeof space === 'undefined') space = 4;
    return JSON.stringify(this, null, space);
};

var m = new MyClass();
console.log(m.toJSON());

I ran it in node.js, and got:

MyClass.prototype.toJSON = function(space) {
                                   ^
RangeError: Maximum call stack size exceeded

I don't know why. It makes me confused. Could you please tell me the reason causing this error? And how to fix it?

4
  • 2
    this in your .toJSON method is a reference to m and stringify will invoke a .toJSON method if it exists on the data it's given. So m.toJSON() calls JSON.stringify(m..., which calls m.toJSON(), which calls JSON.stringify(m..., and so on. Commented Aug 16, 2014 at 5:27
  • That's the answer cookie monster, not just a comment. Here's a comment: You should change if (typeof space === 'undefined') space = 4; to var spc = space ? space : 4;. Then pass spc to JSON.stringify(), as the last argument. Commented Aug 16, 2014 at 5:47
  • 1
    Note that reassigning the argument creates potential scope issues. In this case space could assign a global variable. Commented Aug 16, 2014 at 5:58
  • @PHPglue: Don't worry about posting an answer that was already given as a comment. If a person (like me) decides to use a comment to answer the question, that's their (my) problem. ;-) Commented Aug 16, 2014 at 16:58

3 Answers 3

4

I solved this by renaming the .toJSON function to .save.

I found the reason here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify, which says:

If an object being stringified has a property named toJSON whose value is a function, then the toJSON method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON method when called will be serialized.

So the original code would cause an infinite recursive.

Thanks to @cookie monster and @PHPglue.

Working code:

function MyClass() {
    this.foo = "foo";
    this.bar = "bar";
}

MyClass.prototype.save = function(space) {
    var s = typeof space === 'undefined' ? 0 : 4;
    return JSON.stringify(this, null, s);
};

var m = new MyClass();
console.log(m.save());
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this, it helped in 2023 NodeJS project that was reporting a stack size error due to the recursive calling of a class that has a toJSON() function. MacOS and Windows didn't exhibit this behavior, but it was happening on a Linux server.
0

@cookie monster really answered the question, maybe this will help though:

function MyClass(){
  this.foo = 'foo';
  this.bar = 'bar';
  this.gotToJSON = false;
}

MyClass.prototype.toJSON = function(space){
  var spc = space ? space : 4;
  if(!this.gotToJSON){
    this.gotToJSON = true;
    var result = JSON.stringify(this, null, spc);
    this.gotToJSON = false;
    return result;
  }
  return;
}

var m = new MyClass;
console.log(m.toJSON());

Comments

0

Changing Name

.toJSON

to something else like displayJSON works for me

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.