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

7 浏览
0 Comments

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

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

我想使用JSON.stringify()对这个对象进行序列化,但我遇到了

TypeError: cyclic object value

因为我提到的结构。

我该如何解决这个问题?对我来说,这些引用其他节点的引用是否在序列化的对象中表示都无所谓。

另一方面,在创建这些属性时从对象中删除它们似乎很繁琐,我也不想对解析器(narcissus)进行更改。

admin 更改状态以发布 2023年5月22日
0
0 Comments

这篇文章的替代方案有点不同,但由于很多人会来这里调试他们的循环对象,没有一个很好的方法不需要引入大量的代码进行调试,所以我们来试试。

一个不太广为人知的特性是JSON.stringify()console.table()比这个更好。只需要调用console.table(whatever);,它会以表格的形式在控制台中记录变量,这使得浏览变量的内容变得非常容易和方便。

0
0 Comments

使用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;
});

http://jsfiddle.net/mH6cJ/38/

正如其他评论中正确指出的那样,此代码将删除每个“已看到”的对象,而不仅仅是“递归”的对象。

例如:

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)))

0