У меня есть этот код, основанный на цикле Крокфорда . 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);
Вот снимок экрана указанного объекта c, который я пытаюсь decircularize. Обратите внимание, что ключ next
является ссылкой на следующий объект в двусвязном списке.
Кроме того, subject
указывает на объект window
, так что он также будет содержать некоторые циклические ссылки.
![enter image description here](https://i.stack.imgur.com/bnmlR.png)
Желаемый выход:
![enter image description here](https://i.stack.imgur.com/z4gqG.png)