[英]Preserving undefined that JSON.stringify otherwise removes
How do I preserve undefined
values when doing JSON.stringify(hash)
?执行
JSON.stringify(hash)
时如何保留undefined
的值?
Here's an example:这是一个例子:
var hash = {
"name" : "boda",
"email" : undefined,
"country" : "africa"
};
var string = JSON.stringify(hash);
// > '{"name":"boda","country":"africa"}'
Email disappeared from JSON.stringify
.电子邮件从
JSON.stringify
中消失了。
The JSON spec does not allow undefined
values, but does allow null
values. JSON 规范不允许
undefined
的值,但允许null
值。
You can pass a replacer function to JSON.stringify
to automatically convert undefined
values to null
values, like this:您可以将替换函数传递给
JSON.stringify
以自动将undefined
的值转换为null
值,如下所示:
var string = JSON.stringify(
obj,
function(k, v) { return v === undefined ? null : v; }
);
This works for undefined values inside arrays as well, as JSON.stringify
already converts those to null
.这也适用于数组中的未定义值,因为
JSON.stringify
已经将它们转换为null
。
You can preserve the key by converting to null
since a valid JSON does not allow undefined
;您可以通过转换为
null
来保留密钥,因为有效的 JSON 不允许undefined
;
Simple one liner:简单的一个班轮:
JSON.stringify(obj, (k, v) => v === undefined ? null : v)
This should do the trick这应该可以解决问题
// 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')
Use null
instead of undefined
.使用
null
而不是undefined
。
var hash = {
"name" : "boda",
"email" : null,
"country" : "africa"
};
var string = JSON.stringify(hash);
> "{"name":"boda","email":null,"country":"africa"}"
function stringifyWithUndefined(obj, space) {
const str = JSON.stringify(obj, (key, value) => value === undefined ? '__undefined__' : value, space);
return str.replace(/"__undefined__"/g, 'undefined');
}
Example:例子:
const obj = {
name: 'boda',
email: undefined,
country: 'africa'
};
console.log(stringifyWithUndefined(obj, 2));
Result:结果:
{
"name": "boda",
"email": undefined,
"country": "africa"
}
Im reading between the lines here and guessing that you want to have the value undefined when you use JSON.parse?我在此处阅读并猜测您希望在使用 JSON.parse 时未定义该值?
If that is the case you could use the following:如果是这种情况,您可以使用以下内容:
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
will encode all undefined values in a array and when you call parseAndRestoreUndefined
it will put them in the correct place again. stringifyAndPreserveUndefined
将对数组中的所有未定义值进行编码,当您调用parseAndRestoreUndefined
时,它将再次将它们放在正确的位置。
The one downside is the json will not look exactly like the object.一个缺点是 json 看起来与对象不完全相同。 In the example above it will turn into
{"ROOT":{"test1":"a","test2":"b","test4":{"test1":"a"}},"undefinedPaths":["ROOT.test3","ROOT.test4.test2"]}
在上面的例子中,它将变成
{"ROOT":{"test1":"a","test2":"b","test4":{"test1":"a"}},"undefinedPaths":["ROOT.test3","ROOT.test4.test2"]}
JSON does not have an undefined
value, but we could write a workaround: JSON 没有
undefined
的值,但我们可以编写一个解决方法:
I wrote 2 functions that internally uses JSON.stringify
and JSON.parse
and preserves nested undefined
values using a value placeholder:我编写了 2 个内部使用
JSON.stringify
和JSON.parse
的函数,并使用值占位符保留嵌套的undefined
值:
Equivalent to JSON.stringify
:相当于
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);
}
Equivalent to JSON.parse
:相当于
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;
}
Usage:用法:
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);
Works with both object entries and array items.适用于对象条目和数组项。
The downside is that you have to choose an appropriate placeholder that will not be mistaken via a "real" source value.缺点是您必须选择一个合适的占位符,不会被“真实”源值弄错。 The placeholder is customizable via the optional
undefinedPlaceholder
argument.占位符可通过可选的
undefinedPlaceholder
参数进行自定义。
This is specially useful to store POJO in browser local storage ;)这对于将POJO存储在浏览器本地存储中特别有用;)
See also:也可以看看:
这将导致它打印为undefined
,但这是无效的 json,但它是有效的 JavaScript。
var string = JSON.stringify(obj, function(k,v){return v===undefined?"::undefined::":v}, 2).replace(new RegExp("\"::undefined::\"", 'g'), "undefined");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.