Search code examples
javascriptoopstack-overflow

Fail to `JSON.stringify(this)` when learning OOP (got RangeError: Maximum call stack size exceeded)


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?


Solution

  • 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());