순환 개체 값을 포함하는 개체를 직렬화하는 중
다른 노드에 대한 참조인 하위 노드를 포함하는 개체(파스 트리)가 있습니다.
사물을 JSON.stringify()
나는
TypeError: 순환 객체 값
제가 말씀드린 공사들 때문에요.
내가 어떻게 이 문제를 해결할 수 있을까?다른 노드에 대한 이러한 참조가 직렬화된 개체로 표현되는지 여부는 중요하지 않습니다.
한편, 이러한 속성을 작성할 때 오브젝트에서 삭제하는 것은 귀찮은 일이기 때문에 파서(narcissus)를 변경하고 싶지 않습니다.
는 기껏해야 하다를 사용합니다.stringify
이미 시리얼화된 오브젝트를 제외하려면 , 리페이서 기능을 사용합니다.
var seen = [];
JSON.stringify(obj, function(key, val) {
if (val != null && typeof val == "object") {
if (seen.indexOf(val) >= 0) {
return;
}
seen.push(val);
}
return val;
});
다른 코멘트에서 올바르게 지적된 바와 같이 이 코드는 "재귀적" 객체뿐만 아니라 모든 "보이는" 객체를 삭제합니다.
예를 들어 다음과 같습니다.
a = {x:1};
obj = [a, a];
결과가 틀립니다.구조가 이와 같으면 Crockford의 decycle 또는 재귀 참조를 null로 대체하는 이(심플러) 함수를 사용할 수 있습니다.
function decycle(obj, stack = []) {
if (!obj || typeof obj !== 'object')
return obj;
if (stack.includes(obj))
return null;
let s = stack.concat([obj]);
return Array.isArray(obj)
? obj.map(x => decycle(x, s))
: Object.fromEntries(
Object.entries(obj)
.map(([k, v]) => [k, decycle(v, s)]));
}
//
let a = {b: [1, 2, 3]}
a.b.push(a);
console.log(JSON.stringify(decycle(a)))
이것은 일종의 대안입니다만, 많은 사람들이 여기에 오게 되는 것은 원형 객체를 디버깅하기 위해서입니다.그리고 코드 뭉치를 끌어당기지 않고는 그렇게 할 수 있는 좋은 방법은 없습니다.
」 잘 않다1가지 JSON.stringify()
전화만 하면 됩니다.console.table(whatever);
또한 변수를 표 형식으로 콘솔에 기록하므로 변수의 내용을 보다 쉽고 편리하게 읽을 수 있습니다.
은 순환하는 데이터 입니다. 음음 、 음다 、 다 here 、 다 here here here 。
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
순환 참조를 유지하려면('핵'을 제거하는 대신 역직렬화 시 복원) 두 가지 선택사항이 있습니다. 여기서 비교하겠습니다.첫째는 더글라스 크록포드의 사이클이고 둘째는 시베리아 소포야둘 다 먼저 오브젝트를 "디타이핑"함으로써 동작합니다.즉, (순환 참조 없이) 동일한 정보를 포함하는 다른 오브젝트를 구성합니다.
크록포드 씨가 먼저입니다.
JSON.decycle(makeToolshed())
한 JSON을 입니다.이치노$ref
어떻게 되는지 봅시다.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
달러 기호는 루트를 나타냅니다. .bolt
있다$ref
알 수 있다.bolt
는 " 개체이며,이서 문자열 nut"]["not 수 있습니다(첫 번째 "nut" 참조).견과류 $["nut"]["nut"]["nut"]]])의 경우처음 참조해 주세요.===
두 요.$ref
두 번째 '두 번째'는===
abovedisclossible을 합니다.
Anders Kaseorg' a let let let k test test test test ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ()deepGraphEqual
이 질문에 대한 답변에서 기능)을 수행하여 클로닝이 작동하는지 확인합니다.
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」, 「0」, 「0」, 「0」을 .atoms
array(types array)테이블 는 포레스트 내에 있으며 몇 가 있는지 알 수 즉, "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "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
비교
섹션은 나중에 추가합니다.
메모
저는 현재 패키지를 리팩터링 중입니다.중앙의 아이디어와 알고리즘은 동일하지만, 새로운 버전은 사용하기 쉽고, 최상위 API는 다를 것입니다.곧 시베리아를 보관하고 리팩터 버전을 발표하겠습니다. 오브젝트그래프라고 부르겠습니다.이번 달(2020년 8월)에 개최될 예정이니 잘 부탁드립니다.
아, 그리고 비교는 초단판입니다.포인터의 경우, 「이미 본 노드에의 포인터」(실제로, 이미 본 노드에의 포인터)는 정수일 뿐이기 때문에, 정수만큼의 공간이 필요합니다.Crockford씨 버전에서는 "포인터"를 저장하는 데 필요한 양은 개체 그래프의 크기에 의해서만 제한됩니다.그래서 크록포드 씨 버전의 최악의 경우 복잡성이 극도로 끔찍하게 느껴집니다.크록포드 씨가 '또 다른 버블소트'를 주셨어요너한테 농담하는 거 아니야.그만큼 심각해.믿을 수 없다면 패키지의 readme부터 테스트를 찾을 수 있습니다(benchmark.js 준거로 변환됩니다).
match saver. 사이클 객체가 어디에 있었는지 보여줍니다.
<script>
var jsonify=function(o){
var seen=[];
var jso=JSON.stringify(o, function(k,v){
if (typeof v =='object') {
if ( !seen.indexOf(v) ) { return '__cycle__'; }
seen.push(v);
} return v;
});
return jso;
};
var obj={
g:{
d:[2,5],
j:2
},
e:10
};
obj.someloopshere = [
obj.g,
obj,
{ a: [ obj.e, obj ] }
];
console.log('jsonify=',jsonify(obj));
</script>
생산하다
jsonify = {"g":{"d":[2,5],"j":2},"e":10,"someloopshere":[{"d":[2,5],"j":2},"__cycle__",{"a":[10,"__cycle__"]}]}
순환 구조를 검출하고 해독하여 인코딩할 수 있는 GitHub Gist를 만들었습니다.https://gist.github.com/Hoff97/9842228
변환하려면 JSONE.stringify/JSONE.parse를 사용합니다.또한 기능을 디코딩 및 인코딩합니다.이것을 무효로 하려면 , 32-48 회선과 61-85 회선을 삭제해 주세요.
var strg = JSONE.stringify(cyclicObject);
var cycObject = JSONE.parse(strg);
여기서 바이올린의 예를 찾을 수 있습니다.
http://jsfiddle.net/hoff97/7UYd4/
String과 같이 serializename 속성에 저장하면 cyclic 객체를 시리얼화하고 클래스를 복원할 수 있는 github 프로젝트를 만듭니다.ub 프로젝트를 만듭니다.
var d={}
var a = {b:25,c:6,enfant:d};
d.papa=a;
var b = serializeObjet(a);
assert.equal( b, "{0:{b:25,c:6,enfant:'tab[1]'},1:{papa:'tab[0]'}}" );
var retCaseDep = parseChaine(b)
assert.equal( retCaseDep.b, 25 );
assert.equal( retCaseDep.enfant.papa, retCaseDep );
https://github.com/bormat/serializeStringifyParseCyclicObject
편집: NPM https://github.com/bormat/borto_circular_serialize 의 스크립트를 변환해, 기능명을 프랑스어에서 영어로 변경합니다.
nodejs 모듈은 사이클 또는 javascript 클래스 인스턴스를 포함하는 모든 유형의 JSON 개체를 처리할 수 있는 좋은 방법을 제공합니다.
const { serialize, deserialize } = require("serialijse");
var Mary = { name: "Mary", friends: [] };
var Bob = { name: "Bob", friends: [] };
Mary.friends.push(Bob);
Bob.friends.push(Mary);
var group = [ Mary, Bob];
console.log(group);
// testing serialization using JSON.stringify/JSON.parse
try {
var jstr = JSON.stringify(group);
var jo = JSON.parse(jstr);
console.log(jo);
} catch (err) {
console.log(" JSON has failed to manage object with cyclic deps");
console.log(" and has generated the following error message", err.message);
}
// now testing serialization using serialijse serialize/deserialize
var str = serialize(group);
var so = deserialize(str);
console.log(" However Serialijse knows to manage object with cyclic deps !");
console.log(so);
assert(so[0].friends[0] == so[1]); // Mary's friend is Bob
이 시리얼라이저는
- 객체 정의 사이클
- 클래스 인스턴스 재구성
- 유형 배열, 맵 및 세트 지원
- 시리얼화 프로세스 중에 건너뛸 속성을 필터링할 수 있습니다.
- 유형 배열 바이너리 부호화(Float32)어레이 등)의 퍼포먼스를 향상시킵니다.
function stringifyObject ( obj ) {
if ( _.isArray( obj ) || !_.isObject( obj ) ) {
return obj.toString()
}
var seen = [];
return JSON.stringify(
obj,
function( key, val ) {
if (val != null && typeof val == "object") {
if ( seen.indexOf( val ) >= 0 )
return
seen.push( val )
}
return val
}
);
}
전제 조건이 누락되었습니다.그렇지 않으면 어레이 객체의 정수 값이 잘립니다.[ 08 . 11 . 2014 12 : 30 : 13 , 1095 ]1095가 095로 감소합니다.
언급URL : https://stackoverflow.com/questions/9382167/serializing-object-that-contains-cyclic-object-value
'programing' 카테고리의 다른 글
ng-repeat 내의 ng-click 함수에 파라미터를 추가하는 것이 동작하지 않는 것 같습니다. (0) | 2023.03.18 |
---|---|
$resource, get과 query의 차이점은 무엇입니까? (0) | 2023.03.18 |
PHP 네임스페이스 5.3 및 WordPress 위젯 (0) | 2023.03.18 |
Wordpress에서 현재 게시 ID를 사용하여 다음/이전 게시 ID 가져오기 (0) | 2023.03.18 |
HTML을 JSON에 매핑 (0) | 2023.03.18 |