部分展平的JSON的反序列化

时间:2013-10-09 20:20:08

标签: javascript json

我有一个遗留的API端点,遗憾的是,它只支持平面JSON对象的输出。其中一个输出看起来像这样。

{
    "objects": [
        {
        "id": "1",
        "last-modified": "0",
        "created": "1",
        "name": "Test",
        "fields": "{\"k\":\"v\",\"k2\":\"v2\",\"k3\":[1,2,3],\"k4\":{}}"
        }
    ],
    "attribs": {}
}

虽然这是有效的JSON,但对象的任何嵌套部分都将被字符串化并作为只有一键深度的整体对象返回。当我的JS检索到这个对象时,我尝试使用我写的递归函数反序列化对象的所有可反序列化部分。

var loads = function (obj) {
    var i, buffer;
    if (obj instanceof Array) {
        buffer = [];
        for (i = 0; i < obj.length; i++) {
            buffer.push(loads(obj[i]));
        }
        return buffer;
    } else if (obj instanceof Object) {
        buffer = {};
        for (i in obj) {
            if (obj.hasOwnProperty(i)) {
                buffer[i] = loads(obj[i]);
            }
        }
        return buffer;
    } else if (typeof obj === 'string') {
        return JSON.parse(obj);
    } else {
        return JSON.parse(obj);
    }
};

很明显,递归是错误的,因为此函数会抛出许多“意外令牌”和“意外标识符”错误。

我在这个函数中犯了什么错误,阻止了字符串化JSON值的完全嵌套反序列化?

1 个答案:

答案 0 :(得分:1)

使用JSON.parse的第二个参数简单地恢复安全try块中的代码:

JSON.parse( strOfJSON,  function(k,v){
  try{v=JSON.parse(v)}catch(y){}
 return v
});

输出OP测试代码:

{
    "objects": [
        {
            "id": 1,
            "last-modified": 0,
            "created": 1,
            "name": "Test",
            "fields": {
                "k": "v",
                "k2": "v2",
                "k3": [
                    1,
                    2,
                    3
                ],
                "k4": {}
            }
        }
    ],
    "attribs": {}
}

你可以通过尝试将ID json作为一个字符串来获得更好的并跳过try {},但是这个简单的天真代码可以工作并展示如何使用本机JSON.parse()函数来做你想要的。