Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Noticing an odd difference between different implementations of JSON.stringify

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?

like image 469
Mark Biek Avatar asked Jul 12 '13 15:07

Mark Biek


People also ask

What is specific properties are skipped by JSON Stringify method?

Following JS-specific properties are skipped by JSON.stringify method. Function properties (methods). Symbolic properties. Properties that store undefined.

What does JSON stringify() method do?

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.

What is the difference between toString and JSON Stringify?

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.

How to use JSON stringify in JS?

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.


1 Answers

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.

like image 86
georg Avatar answered Oct 03 '22 19:10

georg