let room = {
number: 23
};
let meetup = {
title: "Совещание",
occupiedBy: [{name: "Иванов"}, {name: "Петров"}],
place: room
};
room.occupiedBy = meetup;
meetup.self = meetup;
alert( JSON.stringify(meetup, function replacer(key, value) {
return (key != "" && value == meetup) ? undefined : value;
}));
/*
{
"title":"Совещание",
"occupiedBy":[{"name":"Иванов"},{"name":"Петров"}],
"place":{"number":23}
}
*/
Initially, the replacer function is called with an empty string as key representing the object being stringified.https://developer.mozilla.org/en-US/docs/Web/JavaS...
key != "" && value == meetup
Переводится как "если ключ не пуст (т.е. не первая итерация, в которой value ссылается на объект целиком) и значение равно искомому объекту, его нужно пропустить и не сериализовывать". Напишите функцию replacer для JSON-преобразования, которая удалит свойства, ссылающиеся на meetup
function makeReplacer() {
const path = [];
return (k, v) => {
// простое значение не записываем в путь
if (!v || typeof v !== 'object') {
return v;
}
// находим родительский объект; всё что глубже, выкидываем
for (let i = path.length - 1; i >= 0; --i) {
const item = path[i];
if (Object.prototype.hasOwnProperty.call(item.obj, k) && item.obj[k] === v && !item.handled.has(k)) {
item.handled.add(k);
break;
} else {
path.pop();
}
}
// если в парентах уже был текущий объект, то игнорируем его
if (path.find((item) => item.obj === v)) {
return undefined;
}
// записываем объект в путь и возвращаем
path.push({
obj: v,
handled: new Set()
});
return v;
};
}
// -----------------------------
// пример использования
let room = {
number: 23
};
let obj1 = {a: {b: room, bb: 23}, c: 34};
let meetup = {
title: "Совещание",
occupiedBy: [room, {name: "Иванов"}, {name: "Петров"}],
place: room
};
room.occupiedBy = meetup;
meetup.self = meetup;
room.self = room;
room.obj1 = obj1;
console.log(JSON.stringify(meetup, makeReplacer(), 4))