상속된 개체를 JSON으로 문자열화하는 방법
JSON.stringify()를 사용할 때 json2.js는 부모 객체의 멤버를 무시하는 것 같습니다.예:
require('./json2.js');
function WorldObject(type) {
this.position = 4;
}
function Actor(val) {
this.someVal = 50;
}
Actor.prototype = new WorldObject();
var a = new Actor(2);
console.log(a.position);
console.log(JSON.stringify(a));
출력은 다음과 같습니다.
4
{"someVal":50}
다음과 같은 출력이 예상됩니다.
4
{"position":0, "someVal":50}
뭐, 원래 그렇긴 하지만JSON.stringify
는 객체의 소유자가 아닌 속성을 보존하지 않습니다.다른 결점과 가능한 회피책에 대한 흥미로운 논의를 여기에서 볼 수 있습니다.
또한 저자는 문제를 문서화할 뿐만 아니라 Hydrate라는 라이브러리도 작성했습니다.JS가 도움이 될 겁니다.
그 문제는 첫눈에 보이는 것보다 조금 더 심각하다.라 할지라도a
에 대해 정말로 엄격히 할 것이다.{"position":0, "someVal":50}
그런 다음 나중에 해석하면 원하는 속성을 가지지만 Actor 인스턴스가 아니며 WorldObject로의 프로토타입 링크도 없는 개체가 생성됩니다(결국 해석 메서드에는 이 정보가 없기 때문에 이러한 방식으로 복원할 수 없습니다).
시제품 체인을 보존하려면 Hydrate에 사용된 것과 같은 교묘한 요령이 필요합니다.JS) 이것이 목적과 다르면 오브젝트를 문자열화하기 전에 "평활화"하면 될 수 있습니다.이를 위해 소유 여부에 관계없이 객체의 모든 속성을 반복하고 재할당할 수 있습니다(이를 통해 프로토타입에서 상속되는 것이 아니라 객체 자체에 정의됩니다).
function flatten(obj) {
var result = Object.create(obj);
for(var key in result) {
result[key] = result[key];
}
return result;
}
함수가 쓰여져 있는 방식으로는 원래 객체가 변형되지 않습니다.그래서 사용하다
console.log(JSON.stringify(flatten(a)));
원하는 결과를 얻을 수 있고a
그대로 있을 거예요.
또 다른 옵션은 다음과 같이 정의하는 것입니다.toJSON
serialize할 객체 프로토타입의 메서드:
function Test(){}
Test.prototype = {
someProperty: "some value",
toJSON: function() {
var tmp = {};
for(var key in this) {
if(typeof this[key] !== 'function')
tmp[key] = this[key];
}
return tmp;
}
};
var t = new Test;
JSON.stringify(t); // returns "{"someProperty" : "some value"}"
이것은 JSON.stringify가 검색하기 때문에 동작합니다.toJSON
네이티브 시리얼화를 시도하기 전에 수신하는 객체의 메서드를 지정합니다.
다음 바이올린을 확인해 주세요.http://jsfiddle.net/AEGYG/
다음 함수를 사용하여 개체를 플랫 문자열화할 수 있습니다.
function flatStringify(x) {
for(var i in x) {
if(!x.hasOwnProperty(i)) {
// weird as it might seem, this actually does the trick! - adds parent property to self
x[i] = x[i];
}
}
return JSON.stringify(x);
}
오브젝트 트리의 여러 레벨에 상속이 있는 경우에 대비하여 그의 답변에 포함된 스니펫 @TomasVana의 재귀 버전을 다음에 나타냅니다.
var flatten = function(obj) {
if (obj === null) {
return null;
}
if (Array.isArray(obj)) {
var newObj = [];
for (var i = 0; i < obj.length; i++) {
if (typeof obj[i] === 'object') {
newObj.push(flatten(obj[i]));
}
else {
newObj.push(obj[i]);
}
}
return newObj;
}
var result = Object.create(obj);
for(var key in result) {
if (typeof result[key] === 'object') {
result[key] = flatten(result[key]);
}
else {
result[key] = result[key];
}
}
return result;
}
어레이를 어레이로 유지합니다.같은 방법으로 불러주세요.
console.log(JSON.stringify(flatten(visualDataViews)));
한편,flatten
일반적인 작업에서 지금까지 게시된 다른 답변의 스니펫은 프로토타입이 동결된 경우처럼 수정할 수 없는 속성에는 작동하지 않습니다.이 문제를 해결하려면 새 개체를 만들고 속성을 이 새 개체에 할당해야 합니다.오브젝트를 문자열화하기만 하면 되기 때문에 오브젝트 ID나 다른 JavaScript의 내부 정보는 상관없습니다.따라서 새로운 오브젝트를 반환해도 문제 없습니다.이 접근법은 오브젝트 속성을 재할당하기보다 읽기 쉬운데, 이는 no-op처럼 보이지 않기 때문입니다.
function flatten(obj) {
var ret = {};
for (var i in obj) {
ret[i] = obj[i];
}
return ret;
}
JSON.stringify(value[, replacer[, space]])
이렇게 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,replacer
각 함수에 으로 호출됩니다.key
-value
--. - - -
다음 문제: 실제로 모든 것을 얻으려면 프로토타입을 따라야 하며 모든 속성 이름을 가져오기 위해 사용해야 합니다(사용할 수 있는 것보다 더 많은 정보를 얻을 수 있습니다.keys
★★★★★★★★★★★★★★★★★」for…in
var getAllPropertyNames = () => {
const seen = new WeakSet();
return (obj) => {
let props = [];
do {
if (seen.has(obj)) return [];
seen.add(obj);
Object.getOwnPropertyNames(obj).forEach((prop) => {
if (props.indexOf(prop) === -1) props.push(prop);
});
} while ((obj = Object.getPrototypeOf(obj)));
return props;
};
};
var flatten = () => {
const seen = new WeakSet();
const getPropertyNames = getAllPropertyNames();
return (key, value) => {
if (value !== null && typeof value === "object") {
if (seen.has(value)) return;
seen.add(value);
let result = {};
getPropertyNames(value).forEach((k) => (result[k] = value[k]));
return result;
}
return value;
};
};
그런 다음 개체를 JSON으로 평탄화합니다.
JSON.stringify(myValue, flatten());
주의:
- i i i i i 。
null
typeof value
"object"
- 순환 참조는 bee를 검출해야 하므로
seen
언급URL : https://stackoverflow.com/questions/8779249/how-to-stringify-inherited-objects-to-json
'programing' 카테고리의 다른 글
UI-Router를 사용하여 페이지 제목 설정 (0) | 2023.03.18 |
---|---|
isPresent 메서드와 isDisplayed 메서드의 차이점은 무엇입니까? (0) | 2023.03.18 |
모든 http 콜에서 디폴트 요구 헤더의 액시오 설정을 작성하려면 어떻게 해야 합니까? (0) | 2023.03.18 |
ui-grid에서 새로 고침 방법을 사용하는 방법 (0) | 2023.03.18 |
wp_enqueue_style이 CSS를 로드하지 않았습니다. (0) | 2023.03.18 |