JSON.stringify가 삭제하지 않은 미정의 보존
보존 방법undefined
할 때의 가치관JSON.stringify(hash)
?
다음은 예를 제시하겠습니다.
var hash = {
"name" : "boda",
"email" : undefined,
"country" : "africa"
};
var string = JSON.stringify(hash);
// > '{"name":"boda","country":"africa"}'
에서 이메일이 사라졌습니다.JSON.stringify
.
JSON 사양에서는 허용되지 않습니다.undefined
값, 단,null
가치.
리페이서 기능을 다음에 전달할 수 있습니다.JSON.stringify
자동적으로 변환하다undefined
에 대한 가치관null
다음과 같은 값:
var string = JSON.stringify(
obj,
function(k, v) { return v === undefined ? null : v; }
);
이는 어레이 내부의 정의되지 않은 값에도 적용됩니다.JSON.stringify
이미 그것들을 로 변환하고 있다.null
.
로 변환하면 키를 유지할 수 있습니다.null
유효한 JSON 에서는,undefined
;
간단한 라이너 1개:
JSON.stringify(obj, (k, v) => v === undefined ? null : v)
이거면 충분할 거야
// Since 'JSON.stringify' hides 'undefined', the code bellow is necessary in
// order to display the real param that have invoked the error.
JSON.stringify(hash, (k, v) => (v === undefined) ? '__undefined' : v)
.replace(/"__undefined"/g, 'undefined')
사용하다null
대신undefined
.
var hash = {
"name" : "boda",
"email" : null,
"country" : "africa"
};
var string = JSON.stringify(hash);
> "{"name":"boda","email":null,"country":"africa"}"
여기 행간을 읽고 JSON.parse를 사용할 때 값을 정의하지 않는 것이 좋다고 생각하십니까?
이 경우 다음을 사용할 수 있습니다.
var encodeUndefined = function(obj, undefinedPaths, path) {
path = path || 'ROOT';
for (var key in obj) {
var keyPath = path + '.' + key;
var value = obj[key];
if (value === undefined) {
undefinedPaths.push(keyPath);
} else if (typeof value == "object" && value !== null) {
encodeUndefined(obj[key], undefinedPaths, keyPath);
}
}
}
var stringifyAndPreserveUndefined = function(obj) {
var undefinedPaths = [];
//save all paths that have are undefined in a array.
encodeUndefined((obj), undefinedPaths);
return JSON.stringify({
ROOT: obj,
undefinedPaths: undefinedPaths
}, function(k, v) { if (v === undefined) { return null; } return v; });
}
var parseAndRestoreUndefined = function(value) {
var data = JSON.parse(value);
var undefinedPaths = data.undefinedPaths;
var obj = data.ROOT;
//Restore all undefined values
for (var pathIndex = 0; pathIndex < undefinedPaths.length; pathIndex++) {
var pathParts = undefinedPaths[pathIndex].substring(5).split('.');
var item = obj;
for (var pathPartIndex = 0; pathPartIndex < pathParts.length - 1; pathPartIndex++) {
item = item[pathParts[pathPartIndex]];
}
item[pathParts[pathParts.length - 1]] = undefined;
}
return obj;
}
var input = {
test1: 'a',
test2: 'b',
test3: undefined,
test4: {
test1: 'a',
test2: undefined
}
};
var result = stringifyAndPreserveUndefined(input);
var result2 = parseAndRestoreUndefined(result);
stringifyAndPreserveUndefined
를 호출하면 어레이 내의 정의되지 않은 모든 값이 인코딩됩니다.parseAndRestoreUndefined
다시 올바른 위치에 놓이게 됩니다.
한 가지 단점은 json이 개체와 완전히 닮지 않는다는 것입니다.위의 예에서는 다음과 같이 변환됩니다.{"ROOT":{"test1":"a","test2":"b","test4":{"test1":"a"}},"undefinedPaths":["ROOT.test3","ROOT.test4.test2"]}
function stringifyWithUndefined(value: any, space: number): string {
const str = JSON.stringify(
value,
(_k, v) => v === undefined ? '__UNDEFINED__' : v,
space
);
return str.replaceAll('"__UNDEFINED__"', 'undefined');
}
예 1:
const object = {
name: 'boda',
email: undefined,
country: 'africa'
};
console.log(stringifyWithUndefined(object, 2));
결과(문자열):
{
"name": "boda",
"email": undefined,
"country": "africa"
}
예 2:
const array = [object, { object }, [[object]]];
console.log(stringifyWithUndefined(array, 2));
결과(문자열):
[
{
"name": "boda",
"email": undefined,
"country": "africa"
},
{
"object": {
"name": "boda",
"email": undefined,
"country": "africa"
}
},
[
[
{
"name": "boda",
"email": undefined,
"country": "africa"
}
]
]
]
주의:undefined
유효한 JSON이 아닙니다.JSON.parse()
에 실패하다SyntaxError: Unexpected token [...] is not valid JSON
라고 하면stringifyWithUndefined()
JSON 에는,undefined
회피책을 작성할 수 있습니다.
중첩된 정의되지 않은 값 보존
내부적으로 사용하는 기능 2개를 작성했습니다.JSON.stringify
그리고.JSON.parse
네스트된 데이터 저장undefined
값 자리 표시자를 사용한 값:
등가JSON.stringify
:
/**
* Serialize a POJO while preserving nested `undefined` values.
*/
function serializePOJO(value, undefinedPlaceholder = "[undefined]") {
const replacer = (key, value) => (value === undefined ? undefinedPlaceholder : value);
return JSON.stringify(value, replacer);
}
등가JSON.parse
:
/**
* Deserialize a POJO while preserving nested `undefined` values.
*/
function deserializePOJO(value, undefinedPlaceholder = "[undefined]") {
const pojo = JSON.parse(value);
if (pojo === undefinedPlaceholder) {
return undefined;
}
// Function that walks through nested values
function deepIterate(value, callback, parent, key) {
if (typeof value === "object" && value !== null) {
Object.entries(value).forEach(([entryKey, entryValue]) => deepIterate(entryValue, callback, value, entryKey));
} else if (Array.isArray(value)) {
value.forEach((itemValue, itemIndex) => deepIterate(itemValue, callback, value, itemIndex));
} else if (parent !== undefined) {
callback(value, parent, key);
}
}
// Replaces `undefined` placeholders
deepIterate(pojo, (value, parent, key) => {
if (value === undefinedPlaceholder) {
parent[key] = undefined;
}
});
return pojo;
}
사용방법:
const source = {
foo : undefined,
bar : {
baz : undefined
}
};
const serialized = serializePOJO(source);
console.log("Serialized", serialized);
// '{"foo":"[undefined]","bar":{"baz":"[undefined]","qux":[1,"[undefined]",2]}}'
const deserialized = deserializePOJO(serialized);
console.log("Deserialized", deserialized);
개체 항목과 배열 항목 모두에서 작동합니다.
단점은 "실제" 소스 값을 통해 실수하지 않는 적절한 자리 표시자를 선택해야 한다는 것입니다.플레이스 홀더는 옵션에서 커스터마이즈 가능undefinedPlaceholder
논쟁.
이것은 POJO를 브라우저 로컬 스토리지에 저장하는 데 특히 유용합니다.
다음 항목도 참조하십시오.
- 개요: https://gist.github.com/yvele/f115f7dd0ed849f918f38b134ec3598a
- JSFiddle:https://jsfiddle.net/n5jt2sf9/
이렇게 하면 다음과 같이 인쇄됩니다.undefined
그러나 이것은 INVALID json이지만 유효한 JavaScript입니다.
var string = JSON.stringify(obj, function(k,v){return v===undefined?"::undefined::":v}, 2).replace(new RegExp("\"::undefined::\"", 'g'), "undefined");
언급URL : https://stackoverflow.com/questions/26540706/preserving-undefined-that-json-stringify-otherwise-removes
'programing' 카테고리의 다른 글
표 형식의 데이터를 JSON으로 어떻게 표현해야 합니까? (0) | 2023.03.17 |
---|---|
Oracle 값 목록에서 선택하는 방법 (0) | 2023.03.17 |
Typescript를 사용하여 Express Request 개체 확장 (0) | 2023.03.17 |
왜 사람들은 리액트/JSX에 { " }을(를) 넣을까요? (0) | 2023.03.17 |
Jest transform Ignore Patterns가 작동하지 않습니다. (0) | 2023.03.17 |