순환 참조가있는 데이터 구조의 예는 다음과 같습니다.
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
순환 참조 ( KEEP) 를 유지 하려면 ( "핵심"대신에 역 직렬화 할 때 복원) 두 가지 중에서 선택할 수 있습니다. 여기에서 비교하겠습니다. 첫 번째는 Douglas Crockford의 cycle.js 이고 두 번째는 내 시베리아 패키지입니다. 둘 다 먼저 객체를 "재순환"하여 (즉, 동일한 정보를 포함하는 다른 순환 참조없이) 다른 객체를 구성합니다.
Crockford 씨가 먼저갑니다 :
JSON.decycle(makeToolshed())
보시다시피 JSON의 중첩 구조는 유지되지만 특별한 $ref
속성을 가진 객체 인 새로운 것이 있습니다. 그것이 어떻게 작동하는지 봅시다.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
달러 기호는 루트를 나타냅니다. .bolt
있는 것은 $ref
라고 우리에게 이야기 .bolt
에 "이미 본"개체이며, 먼저 볼 경우 특별한 속성의 값이 (여기에서, 문자열 $ [ "너트"] [ "필요"]) 우리에게 ===
위. 두 번째 $ref
와 두 번째도 마찬가지입니다 ===
.
복제가 작동하는지 확인 하기 위해 적절한 심도 평등 테스트 (즉, 이 질문에 대한deepGraphEqual
답변에서 Anders Kaseorg의 기능 )를 사용하십시오.
root = makeToolshed();
clone = JSON.retrocycle(JSON.decycle(root));
deepGraphEqual(root, clone) // true
serialized = JSON.stringify(JSON.decycle(root));
clone2 = JSON.retrocycle(JSON.parse(serialized));
deepGraphEqual(root, clone2); // true
시베리아
JSON.Siberia.forestify(makeToolshed())
시베리아는 "클래식"JSON을 모방하려고 시도하지 않고 중첩 구조를 사용하지 않습니다. 객체 그래프는 "평평한"방식으로 설명됩니다. 객체 그래프의 각 노드는 플랫 트리 (정수 전용 값을 갖는 일반 키 값 쌍 목록)로 바뀝니다 .forest.
. 인덱스 0 의 항목 은 루트 객체를 찾고 높은 지수에서는 다른 노드를 찾습니다. 개체 그래프와 (포리스트 트리의 일부 키에 대한 음수 값)은 atoms
배열을 가리 킵니다 (유형 배열을 통해 입력되지만 여기서는 입력 세부 정보를 건너 뜁니다). 모든 터미널 노드는 원자 테이블에 있고 모든 비 터미널 노드는 포리스트 테이블에 있으며 개체 그래프에있는 노드 수를 즉시 확인할 수 있습니다 forest.length
. 작동하는지 테스트 해 봅시다.
root = makeToolshed();
clone = JSON.Siberia.unforestify(JSON.Siberia.forestify(root));
deepGraphEqual(root, clone); // true
serialized = JSON.Siberia.stringify(JSON.Siberia.forestify(root));
clone2 = JSON.Siberia.unforestify(JSON.Siberia.unstringify(serialized));
deepGraphEqual(root, clone2); // true
비교
나중에 섹션을 추가합니다.