Ситуация: вы работаете с объектами в JavaScript и решили преобразовать их в JSON для отправки на сервер. Создали объект, добавили в него данные — и вроде всё сделали по правилам:
// Создаём объект
const user = {
name: "Алексей",
role: "developer"
};
// Создаём новый объект на основе первого
user.self = user;
// Преобразовываем всё в JSON
const jsonData = JSON.stringify(user); // Ошибка!
Но при запуске получаем ошибку:
❌ TypeError: cyclic object value
Что это значит: ошибка возникает, когда объект содержит циклические ссылки — то есть одно из его свойств ссылается на сам объект или на другой объект, который, в свою очередь, ссылается обратно. Это создаёт бесконечную вложенность, которую невозможно корректно преобразовать в JSON или обработать в операциях, требующих обхода структуры данных.
Когда встречается:
- При сериализации объектов с циклическими ссылками через JSON.stringify().
- При попытке копирования объектов с циклическими зависимостями.
- В библиотеках для работы с данными, которые не поддерживают такие ссылки (например, некоторые реализации глубокого копирования).
Что делать с ошибкой TypeError: cyclic object value
Общее решение такое: нужно разорвать циклическую ссылку в структуре данных или использовать специальные методы для обработки таких случаев.
Допустим, у вас есть два объекта, которые ссылаются друг на друга:
const objA = { name: "A" };
const objB = { name: "B" };
objA.link = objB;
objB.link = objA; // Циклическая ссылка
JSON.stringify(objA); // Ошибка!
Что с этим можно сделать, покажем дальше.
Удалить циклические ссылки
Если они не нужны, просто исключите их из структуры (совет капитанский, но работает):
delete objA.link;
delete objB.link;
Использовать параметр replacer в JSON.stringify()
Этот параметр позволяет преобразовывать несмотря ни на что или игнорировать определённые свойства:
const jsonData = JSON.stringify(objA, (key, value) => {
if (key === "link") return undefined; // Игнорируем свойство "link"
return value;
});
Использовать библиотеки для обработки циклических ссылок
Например, библиотека flatted
(npmjs.com/package/flatted) умеет сериализовывать такие объекты:
import { stringify } from 'flatted';
const jsonData = stringify(objA); // Работает!
Как исправить ошибку из примера
Сделаем два варианта: удалим ссылку user.self
перед сериализацией или используем replacer
. Переписывать весь код не будем, просто изменим концовку:
// Вариант 1
delete user.self;
const jsonData = JSON.stringify(user);
// Вариант 2
const jsonData = JSON.stringify(user, (key, value) => {
if (key === "self") return undefined;
return value;
});
Вам слово
Приходите к нам в соцсети поделиться своим мнением об ошибке, а также встречалась ли она у вас, и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте: шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!