序列化包含循环对象值的对象
2022-08-30 01:54:33
我有一个对象(解析树),其中包含对其他节点的引用子节点。
我想使用 序列化此对象,但我得到JSON.stringify()
类型错误:循环对象值
因为我提到的结构。
我该如何解决这个问题?对我来说,这些对其他节点的引用是否在序列化对象中表示并不重要。
另一方面,在创建这些属性时从对象中删除这些属性似乎很乏味,我不想对解析器(narcissus)进行更改。
我有一个对象(解析树),其中包含对其他节点的引用子节点。
我想使用 序列化此对象,但我得到JSON.stringify()
类型错误:循环对象值
因为我提到的结构。
我该如何解决这个问题?对我来说,这些对其他节点的引用是否在序列化对象中表示并不重要。
另一方面,在创建这些属性时从对象中删除这些属性似乎很乏味,我不想对解析器(narcissus)进行更改。
使用 的第二个参数 ,即 replacer 函数,排除已序列化的对象: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或这个(更简单的)函数,它只是用nulls替换递归引用:
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)))
这是一种替代答案,但是由于很多人来这里是为了调试他们的循环对象,并且没有一个很好的方法来做到这一点,而无需拉入一堆代码,所以这里去了。
一个不如 console.table()
那么出名的功能。只需调用 ,它就会以表格格式在控制台中记录变量,这使得仔细阅读变量的内容变得相当容易和方便。JSON.stringify()
console.table(whatever);