【发布时间】:2020-04-02 14:51:35
【问题描述】:
我的这段代码基于 Crockford 的 cycle.js,但它从输入对象中删除的内容超出了应有的范围。由于某种原因,它几乎可以识别缓存中已经看到的所有内容并跳过它。
我不完全确定 WeakMap 与 Set 相比有何意义,因此这可能是问题的一部分。我已经尝试将两者互换,但似乎没有什么不同。
这是代码。我已经让它足够独立了,你应该可以把它放到浏览器控制台中。
const message = (function cloneWithoutCircularReferences(object) {
const cache = new WeakMap();
const clone = Array.isArray(object) ? [] : {};
function getKeyOfObjectByPath(object, path) {
return path.reduce(function(object, key) {
return object[key];
}, clone) || clone;
}
(function traverse(object, path = []) {
try {
for (const [key, value] of Object.entries(object)) {
if (typeof object === "object" && object !== null) {
if (cache.has(object)) {
continue;
}
cache.set(object, path);
getKeyOfObjectByPath(object, path)[key] = Array.isArray(object[key]) ? [] : {};
traverse(value, [...path, key]);
} else {
getKeyOfObjectByPath[key] = value;
}
}
} catch (error) { }
})(object);
return clone;
})(globalThis); // I'm using `globalThis` since it's an easily accessible object with circular references. The actual object I want to decircularize is an array of doubly linked objects.
console.log(message);
这是我尝试去环化的特定对象的屏幕截图。注意next 键是对双向链表中下一个对象的引用。
此外,subject 指向 window 对象,因此它也将包含一些循环引用。
期望的输出:
【问题讨论】:
-
明显的问题是,在循环引用中,你不知道循环从哪里开始,你应该开始跳过一些东西
-
请发布“我想要去循环化的实际对象 [that] 是一个双向链表/对象数组”以及您期望得到的结果。
-
@Bergi Done,尽我所能。
-
我的意思是,您能否发布构建您遇到问题的结构对象的代码,以及所需的 JSON 输出?我真的不知道你想省略的
next属性有什么特别之处 -
我已经确定我真正需要的是一个基于 BFS 的克隆函数,它带有一个缓存来清除看到的元素。 DFS 在这里帮不了我。
标签: javascript clone circular-reference