一尘不染

序列化包含循环对象值的对象

javascript

我有一个对象(解析树),其中包含子节点,这些子节点是对其他节点的引用。

我想使用序列化此对象JSON.stringify(),但是我得到了

TypeError:循环对象值

因为我提到的结构。

我该如何解决?对我而言,在序列化对象中是否表示对其他节点的引用并不重要。

另一方面,在创建对象时将这些属性从对象中删除似乎很乏味,我也不想对解析器(水仙)进行更改。


阅读 315

收藏
2020-05-01

共1个答案

一尘不染

使用的第二个参数stringify,该替代品的功能,以排除已序列化对象:

var seen = [];

JSON.stringify(obj, function(key, val) {
   if (val != null && typeof val == "object") {
        if (seen.indexOf(val) >= 0) {
            return;
        }
        seen.push(val);
    }
    return val;
});

正如在其他注释中正确指出的那样,此代码删除了每个“可见”对象,而不仅仅是“递归”对象。

例如,用于:

a = {x:1};
obj = [a, a];

结果将不正确。如果您的结构是这样的,则可能要使用Crockford的decycle或此(简单的)函数,该函数仅将递归引用替换为null:

function decycle(obj, stack = []) {

    if (!obj || typeof obj !== 'object')

        return obj;



    if (stack.includes(obj))

        return null;



    let s = stack.concat([obj]);



    return Array.isArray(obj)

        ? obj.map(x => decycle(x, s))

        : Object.fromEntries(

            Object.entries(obj)

                .map(([k, v]) => [k, decycle(v, s)]));

}



//



let a = {b: [1, 2, 3]}

a.b.push(a);



console.log(JSON.stringify(decycle(a)))
2020-05-01