Let's say I have a fairly nested JS object like this and I need to JSON-encode it:
var foo = {
"totA": -1,
"totB": -1,
"totC": "13,052.00",
"totHours": 154,
"groups": [
{"id": 1,
"name": "Name A",
"billingCodes": [
{"bc": "25", "type": "hours", "hours": "5", "amount": "$25.00"}
]}
]
};
If I JSON-encode it using the native browser JSON.stringify
(tested in Chrome, Firefox, IE9/10), I get back a JSON string that looks like this (which is what I expect):
Native JSON.stringify JSFiddle example
{
"totA": -1,
"totB": -1,
"totC": "13,052.00",
"totHours": 154,
"groups": [
{
"id": 1,
"name": "Name A",
"billingCodes": [
{
"bc": "25",
"type": "hours",
"hours": "5",
"amount": "$25.00"
}
]
}
]
}
The weirdness comes in if I try to do the same thing on a page that's using either PrototypeJS or json2.js.
In that case, JSON.stringify
on the same object gives me back the following JSON:
ProtypeJS JSON.stringify JSFiddle example
{
"totA": -1,
"totB": -1,
"totC": "13,052.00",
"totHours": 154,
"groups": "[{\"id\": 1, \"name\": \"Name A\", \"billingCodes\": [{\"bc\": \"25\", \"type\": \"hours\", \"hours\": \"5\", \"amount\": \"$25.00\"}]}]"
}
Obviously, the above is a problem because it doesn't JSON-decode to the same object that was originally passed to JSON.stringify
.
Can anyone elaborate on what's going on and why there's this difference?
What am I missing?
Following JS-specific properties are skipped by JSON.stringify method. Function properties (methods). Symbolic properties. Properties that store undefined.
The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
stringify when you want to get a JSON that represents the value it has, be it an object, an array, a date, and so on. This is common in exchange for information, such as sending and receiving values for API's. While toString is common to be used to get a text representation of the object in question.
Use the JavaScript function JSON.stringify() to convert it into a string. const myJSON = JSON.stringify(obj); The result will be a string following the JSON notation.
This is because native JSON.stringify
respects toJSON
methods, and Prototype adds these all over the place. Unfortunately, native and Prototype appear to understand toJSON
in different ways: while native expects it to return a string, which is used as a literal value, Prototype's toJSON
returns chunks of already formatted JSON which are meant to be used as is. Hence the discrepancy.
This works fine:
delete Array.prototype.toJSON;
document.getElementById('out').innerHTML += JSON.stringify(foo);
http://jsfiddle.net/Ky3tv/2/
Also, this appears to be fixed in Prototype 1.7. I guess they're now checking for native JSON before adding their toJSON
methods.
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