Eu tenho um objeto (árvore de análise) que contém nós filhos que são referências a outros nós.
Eu gostaria de serializar esse objeto usando JSON.stringify()
, mas recebo
TypeError: valor do objeto cíclico
por causa das construções que mencionei.
Como eu poderia resolver isso? Não me importa se essas referências a outros nós estão representadas ou não no objeto serializado.
Por outro lado, remover essas propriedades do objeto quando elas estão sendo criadas parece entediante e eu não gostaria de fazer alterações no analisador (narciso).
javascript
json
jsonserializer
stringify
Loic Duros
fonte
fonte
cycle.js
resposta de Douglas Crockford aqui, já que é a solução mais apropriada para muitos casos. Parece apropriado que você poste essa resposta, já que você é o primeiro a fazer referência a ela (no seu comentário abaixo). Se você não quiser publicá-lo como uma resposta, acabarei por fazê-lo.Respostas:
Use o segundo parâmetro de
stringify
, a função substituta , para excluir objetos já serializados:http://jsfiddle.net/mH6cJ/38/
Como apontado corretamente em outros comentários, esse código remove todos os objetos "vistos", não apenas os "recursivos".
Por exemplo, para:
o resultado estará incorreto. Se sua estrutura for assim, convém usar o decycle de Crockford ou essa função (mais simples) que substitui as referências recursivas por nulos:
fonte
Eu criei um GitHub Gist que é capaz de detectar estruturas cíclicas e também de- e as codifica: https://gist.github.com/Hoff97/9842228
Para transformar basta usar JSONE.stringify / JSONE.parse. Também decodifica e codifica funções. Se você quiser desativar isso, remova as linhas 32-48 e 61-85.
Você pode encontrar um exemplo de violino aqui:
http://jsfiddle.net/hoff97/7UYd4/
fonte
Essa é uma resposta alternativa, mas como muitas pessoas virão aqui para depurar seus objetos circulares e não há realmente uma ótima maneira de fazer isso sem inserir um monte de código, aqui vai.
Um recurso que não é tão conhecido como
JSON.stringify()
éconsole.table()
. Basta ligarconsole.table(whatever);
e ele registrará a variável no console em formato de tabela, tornando bastante fácil e conveniente ler o conteúdo da variável.fonte
muito mais econômico e mostra onde estava um objeto de ciclo .
produz
fonte
obj.b=this'
se alguém sabe como evitar muito longas calcs feitas de um determinado escopo de errado comthis
seria bom para ver aquiseen.indexOf(v) != -1
Também crio um projeto no github que pode serializar objetos cíclicos e restaurar a classe se você o salvar no atributo serializename como uma String
https://github.com/bormat/serializeStringifyParseCyclicObject
Edit: Transformei meu script para NPM https://github.com/bormat/borto_circular_serialize e alterei os nomes das funções de francês para inglês.
fonte
Aqui está um exemplo de uma estrutura de dados com referências cíclicas:
Quando desejar MANTENHA as referências cíclicas (restaurá-los quando você desserializar, em vez de "nuking-los"), você tem 2 opções, o que eu vou comparar aqui. O primeiro é o cycle.js de Douglas Crockford , o segundo é o meu pacote da Sibéria . Ambos trabalham primeiro "deciclando" o objeto, ou seja, construindo outro objeto (sem nenhuma referência cíclica) "contendo a mesma informação".
O Sr. Crockford vai primeiro:
Como você vê, a estrutura aninhada do JSON é mantida, mas há uma coisa nova, que é objetos com a
$ref
propriedade especial . Vamos ver como isso funciona.O cifrão representa a raiz.
.bolt
ter$ref
nos diz que.bolt
é um objeto "já visto" e o valor dessa propriedade especial (aqui, a string $ ["nut"] ["needs"]) nos diz onde, veja primeiro===
acima. Da mesma forma para o segundo$ref
e o segundo===
acima.Vamos usar um teste de igualdade profunda adequado (ou seja, a
deepGraphEqual
função de Anders Kaseorg da resposta aceita a esta pergunta ) para ver se a clonagem funciona.Agora, na Sibéria:
A Sibéria não tenta imitar JSON "clássico", nenhuma estrutura aninhada. O gráfico do objeto é descrito de maneira "plana". Cada nó do gráfico de objeto é transformado em uma árvore plana (lista de pares de valores de chave simples com valores somente inteiros), que é uma entrada em
.forest.
No índice zero, encontramos o objeto raiz, em índices mais altos, encontramos os outros nós de o gráfico do objeto e os valores negativos (de alguma chave de alguma árvore da floresta) apontam para aatoms
matriz (que é digitada através da matriz de tipos, mas pularemos os detalhes da digitação aqui). Todos os nós terminais estão na tabela de átomos, todos os nós não terminais estão na tabela de floresta e é possível ver imediatamente quantos nós o gráfico de objetos possui, a saberforest.length
. Vamos testar se funciona:comparação
adicionará a seção mais tarde.
fonte
Faltava uma pré-condição, caso contrário, os valores inteiros nos objetos da matriz são truncados, ou seja, [[08.11.2014 12:30:13, 1095]] 1095 é reduzido para 095.
fonte