注意到JSON.stringify的不同实现之间有一个奇怪的差异

Noticing an odd difference between different implementations of JSON.stringify

本文关键字:有一个 之间 实现 JSON stringify 注意到      更新时间:2023-09-26

假设我有一个像这样嵌套的JS对象,我需要对它进行JSON编码:

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"}
        ]}
    ] 
};

如果我使用本地浏览器JSON.stringify(在Chrome、Firefox、IE9/10中测试)对其进行JSON编码,我会返回一个JSON字符串,如下所示(这就是我所期望的):

原生JSON.stringify JSFiddle示例

{
    "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"
                }
            ]
        }
    ]
}

如果我试图在一个使用PrototypeJS或json2.js的页面上做同样的事情,就会出现奇怪的情况

在这种情况下,同一对象上的JSON.stringify会返回以下JSON:

ProtypeJS JSON.stringify JSFiddle示例

{
    "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'"}]}]"
}

显然,上述内容是一个问题,因为它没有对最初传递给JSON.stringify的同一对象进行JSON解码。

有人能详细说明发生了什么以及为什么会有这种差异吗?

我错过了什么?

这是因为原生JSON.stringify尊重toJSON方法,而Prototype在所有地方都添加了这些方法。不幸的是,native和Prototype似乎以不同的方式理解toJSON:虽然native希望它返回一个字符串,该字符串用作文字值,但Prototype的toJSON返回的是已经格式化的JSON块,这些JSON块本应按原样使用。因此存在差异。

这很好:

delete Array.prototype.toJSON;
document.getElementById('out').innerHTML += JSON.stringify(foo);

http://jsfiddle.net/Ky3tv/2/

此外,这似乎在原型1.7中得到了修复。我猜他们在添加toJSON方法之前,现在正在检查原生JSON。

相关文章: