순환 참조를 사용하여 JavaScript 개체 문자열 지정(JSON으로 변환)
순환 참조를 포함하는 JavaScript 개체 정의를 가지고 있습니다. 상위 개체를 참조하는 속성이 있습니다.
서버에 전달하고 싶지 않은 기능도 있습니다.이러한 오브젝트를 시리얼화 및 시리얼 해제하려면 어떻게 해야 합니까?
이것을 하는 가장 좋은 방법은 Douglas Crockford의 Stringify를 사용하는 것이라고 읽었습니다.그러나 Chrome에서 다음과 같은 오류가 발생합니다.
TypeError: 원형 구조를 JSON으로 변환하는 중
코드:
function finger(xid, xparent){
this.id = xid;
this.xparent;
//other attributes
}
function arm(xid, xparent){
this.id = xid;
this.parent = xparent;
this.fingers = [];
//other attributes
this.moveArm = function() {
//moveArm function details - not included in this testcase
alert("moveArm Executed");
}
}
function person(xid, xparent, xname){
this.id = xid;
this.parent = xparent;
this.name = xname
this.arms = []
this.createArms = function () {
this.arms[this.arms.length] = new arm(this.id, this);
}
}
function group(xid, xparent){
this.id = xid;
this.parent = xparent;
this.people = [];
that = this;
this.createPerson = function () {
this.people[this.people.length] = new person(this.people.length, this, "someName");
//other commands
}
this.saveGroup = function () {
alert(JSON.stringify(that.people));
}
}
이것은 제가 이 질문을 위해 만든 테스트 케이스입니다.이 코드에는 오류가 있지만 기본적으로 개체 내에 개체가 있고 개체 생성 시 상위 개체가 무엇인지 보여주는 참조가 각 개체에 전달됩니다.각 오브젝트에는 함수도 포함되어 있기 때문에 문자열화하지 않습니다.나는 단지 다음과 같은 속성을 원한다.Person.Name
.
서버에 송신하기 전에 시리얼화해, 같은 JSON이 반송되는 것을 전제로 해 시리얼화를 해제하려면 어떻게 해야 합니까?
원형 구조 오류는 개체 자체의 속성을 직접 가지고 있는 경우 발생합니다(a -> a
간접적으로 「 「」 「」)a -> b -> a
를 참조해 주세요.
에러 메시지를 회피하려면 , 순환 참조가 발생했을 경우에 JSON.stringify 에 대처 방법을 지시합니다.예를 들어, 다른 사용자("상위")를 가리키는 사용자가 있는 경우, 원래 사용자를 가리킬 수도 있고 가리킬 수도 없는 경우 다음을 수행하십시오.
JSON.stringify( that.person, function( key, value) {
if( key == 'parent') { return value.id;}
else {return value;}
})
는 " " " 입니다.stringify
필터 함수입니다.여기서는 참조된 오브젝트를 해당 ID로 변환하기만 하면 됩니다.단, 순환 참조를 해제하는 것은 자유롭게 할 수 있습니다.
위의 코드는 다음과 같이 테스트할 수 있습니다.
function Person( params) {
this.id = params['id'];
this.name = params['name'];
this.father = null;
this.fingers = [];
// etc.
}
var me = new Person({ id: 1, name: 'Luke'});
var him = new Person( { id:2, name: 'Darth Vader'});
me.father = him;
JSON.stringify(me); // so far so good
him.father = me; // time travel assumed :-)
JSON.stringify(me); // "TypeError: Converting circular structure to JSON"
// But this should do the job:
JSON.stringify(me, function( key, value) {
if(key == 'father') {
return value.id;
} else {
return value;
};
});
저는 다른 을 '어울리다', '어울리다', 어울리다'로 parent
여러 언어(및 DOM)에서 사용되는 예약어이기 때문입니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
립 없음
아래 리페이서를 사용하여 중복/원 참조된 개체에 대한 문자열 참조(json-path와 유사)를 가진 json을 생성합니다.
let s = JSON.stringify(obj, refReplacer());
function refReplacer() {
let m = new Map(), v= new Map(), init = null;
return function(field, value) {
let p= m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field);
let isComplex= value===Object(value)
if (isComplex) m.set(value, p);
let pp = v.get(value)||'';
let path = p.replace(/undefined\.\.?/,'');
let val = pp ? `#REF:${pp[0]=='[' ? '$':'$.'}${pp}` : value;
!init ? (init=value) : (val===init ? val="#REF:$" : 0);
if(!pp && isComplex) v.set(value, path);
return val;
}
}
// ---------------
// TEST
// ---------------
// gen obj with duplicate references
let a = { a1: 1, a2: 2 };
let b = { b1: 3, b2: "4" };
let obj = { o1: { o2: a }, b, a }; // duplicate reference
a.a3 = [1,2,b]; // circular reference
b.b3 = a; // circular reference
let s = JSON.stringify(obj, refReplacer(), 4);
console.log(s);
그리고 이러한 "ref-json"에서 객체를 재생성하는 파서 기능을 따라갑니다.
function parseRefJSON(json) {
let objToPath = new Map();
let pathToObj = new Map();
let o = JSON.parse(json);
let traverse = (parent, field) => {
let obj = parent;
let path = '#REF:$';
if (field !== undefined) {
obj = parent[field];
path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
}
objToPath.set(obj, path);
pathToObj.set(path, obj);
let ref = pathToObj.get(obj);
if (ref) parent[field] = ref;
for (let f in obj) if (obj === Object(obj)) traverse(obj, f);
}
traverse(o);
return o;
}
// ------------
// TEST
// ------------
let s = `{
"o1": {
"o2": {
"a1": 1,
"a2": 2,
"a3": [
1,
2,
{
"b1": 3,
"b2": "4",
"b3": "#REF:$.o1.o2"
}
]
}
},
"b": "#REF:$.o1.o2.a3[2]",
"a": "#REF:$.o1.o2"
}`;
console.log('Open Chrome console to see nested fields:');
let obj = parseRefJSON(s);
console.log(obj);
dojo는 JSON에서 다음과 같은 형식으로 순환 참조를 나타낼 수 있습니다.{"id":"1","me":{"$ref":"1"}}
다음은 예를 제시하겠습니다.
require(["dojox/json/ref"], function(){
var me = {
name:"Kris",
father:{name:"Bill"},
mother:{name:"Karen"}
};
me.father.wife = me.mother;
var jsonMe = dojox.json.ref.toJson(me); // serialize me
alert(jsonMe);
});
작성:
{
"name":"Kris",
"father":{
"name":"Bill",
"wife":{
"name":"Karen"
}
},
"mother":{
"$ref":"#father.wife"
}
}
주의: 이러한 순환 참조 오브젝트의 시리얼화를 해제하려면dojox.json.ref.fromJson
방법.
기타 자원:
순환 참조가 있는 경우에도 DOM 노드를 JSON으로 시리얼화하려면 어떻게 해야 합니까?
JSON.stringify는 순환 참조를 나타낼 수 없습니다.
JSON에서 순환 참조를 처리할 수 있는 두 개의 적절한 모듈을 찾았습니다.
- CircularJSON https://github.com/WebReflection/circular-json. 출력은 .dll에 대한 입력으로 사용할 수 있습니다.브라우저 및 Node.js에서도 사용할 수 있습니다.또, 다음의 URL도 참조해 주세요.http://webreflection.blogspot.com.au/2013/03/solving-cycles-recursions-and-circulars.html
- Isaacs json-stringify-safe https://github.com/isaacs/json-stringify-safe은 가독성이 향상될 수 있지만 .vl에서는 사용할 수 없으며 Node.js에서만 사용할 수 있습니다.
어느 쪽이든 고객의 요구를 만족시킬 수 있습니다.
리모트 디버깅을 할 수 없었기 때문에 복잡한 오브젝트를 페이지에 기록해야 했기 때문에 이 스레드가 발생하였습니다.Douglas Crockford(JSON의 inceptor) 자신의 cycle.js를 찾았습니다.이것은, 구문 분석 후에 다시 접속할 수 있도록, 문자열등의 순환 참조에 주석을 붙입니다.사이클 해제된 딥 복사는 JSON.stringify를 통과해도 안전합니다.맛있게 드세요!
https://github.com/douglascrockford/JSON-js
cycle.cycle:이 파일에는 JSON.decycle과 JSON.retrocycle의 2가지 함수가 포함되어 있으며, 이를 통해 JSON에서 순환 구조 및 대그를 인코딩한 후 복구할 수 있습니다.이는 ES5에서는 제공되지 않는 기능입니다.JSONPath는 링크를 나타내기 위해 사용됩니다.
순환 참조를 제거하기 위해 다음을 사용했습니다.
JS.dropClasses = function(o) {
for (var p in o) {
if (o[p] instanceof jQuery || o[p] instanceof HTMLElement) {
o[p] = null;
}
else if (typeof o[p] == 'object' )
JS.dropClasses(o[p]);
}
};
JSON.stringify(JS.dropClasses(e));
언급URL : https://stackoverflow.com/questions/10392293/stringify-convert-to-json-a-javascript-object-with-circular-reference
'itsource' 카테고리의 다른 글
React 컴포넌트의 양식에 검증을 추가하려면 어떻게 해야 합니까? (0) | 2023.03.08 |
---|---|
$rootScope에 액세스할 수 없습니다. (0) | 2023.02.26 |
Spring Boot에서 Cache-Control 헤더를 정적 리소스에 추가하려면 어떻게 해야 합니까? (0) | 2023.02.26 |
잭슨:열거형 값을 정수로 직렬화 및 직렬화 해제 (0) | 2023.02.26 |
Oracle IN 절에 1000개 이상의 값을 입력하는 방법 (0) | 2023.02.26 |