I wanted to add a .toJson
method to an instantiated JavaScript object, which would allow me to get the stringified object instance without functions and prototype, to transmit during a request.
However, it seems like the actual name of the function 'toJSON' as a method name impacts the ability of JavaScript engine (at least in V8) to run the function - that is, if you rename the same exact function to "JSON" instead of "toJSON", it works, however, as "toJSON", it causes a Maximum Callstack error. See example:
function P1(name, age){
this.name = name;
this.age= age;
this.toJSON = function(){
return JSON.stringify(this);
}
}
function P2(name, age){
this.name = name;
this.age= age;
this.JSON = function(){
return JSON.stringify(this);
}
}
// This causes an error: Uncaught RangeError: Maximum call stack size exceeded(…)
var p1 = new P1('Memory Error', 10);
try {
p1.toJSON();
} catch(e){
console.log(e);
}
var p2 = new P2('No Error', 20);
p2.JSON();
Is this an expected behavior of JavaScript? Does it have something to do with "toJSON" being a native method (note: I have verified that on an instantiated object as above, there is no toJSON method on the prototype that would interfere with a redefinition on the instance)? I am trying to determine if I should report this as a bug to V8 team, or this is explainable by someone who knows more about the spec.
Thanks
This is not what the .toJSON
method is used for. You use .toJSON
to override the default stringification behavior. The .toJSON
is called internally by JSON.stringify
, you don't need to call it on your own. .toJSON
can return a string, object, array, whatever you want to be stringified in the response from JSON.stringify
.
Your .toJSON
method needs to do something other than call JSON.stringify(this)
. Right now you are getting an infinite loop since JSON.stringify(this)
calls the object's .toJSON
, and so on.
Try something like this:
function P1(name, age){
this.name = name;
this.age= age;
this.toJSON = function(){
return {
name: this.name,
age: this.age
};
}
}
var p1 = new P1('Test', 10);
console.log(JSON.stringify(p1));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With