undefined
不是有效的 JSON 值,因此我使用自定义替换函数来序列化它。效果很好。但是,当反序列化它时,它适用于值和数组(因此我的 reviver 函数似乎有效),但不适用于未定义键消失的对象。我做错了什么?
function serialize(data) {
return JSON.stringify(data, function (key, value) {
if (this[key] === undefined) {
return '__undef__'
}
return value
})
}
function deserialize(data) {
return JSON.parse(data, function (key, value) {
if (this[key] === '__undef__') {
return undefined
}
return value
})
}
const undef = undefined
const obj1 = { undef: undefined }
console.log(serialize(undefined));
console.log(deserialize(serialize(undefined)));
console.log(serialize([undefined]));
console.log(deserialize(serialize([undefined])));
console.log(serialize({ undef: undefined }));
console.log(deserialize(serialize({ undef: undefined })));
您的问题基本上是 [ <1 empty item> ] 是由于 JavaScript 处理带有空项的数组的方式造成的。当未定义被放置在序列化然后反序列化的数组中时,结果将具有命名的“洞”,而不是像您想要的那样显式未定义值。
因为像 jabaa 提到的那样,“如果 reviver 函数返回未定义(或不返回任何值 - 例如,如果执行落在函数末尾),则该属性将从对象中删除。”,source .
要解决此问题,您必须添加一个自定义方法来处理服务和反序列化,该方法考虑到未定义的值,以便它们不会被语言视为“漏洞”
function serialize(data) {
return JSON.stringify(data, function (key, value) {
return value === undefined ? '__undef__' : value;
});
}
function deserialize(data) {
const parsedArray = JSON.parse(data, function(key, value) {
if (this[key] === '__undef__') {
return undefined
}
});
if (Array.isArray(parsedArray)) {
for (let i = 0; i < parsedArray.length; i++) {
// if i in parsedArray returns false if there is no value (thus empty item), so we just change it to undefined
if (!(i in parsedArray)) {
parsedArray[i] = undefined;
}
}
}
return parsedArray;
}
const undef = undefined;
const obj1 = { undef: undefined };
console.log(serialize(undefined)); // "__undef__"
console.log(deserialize(serialize(undefined))); // undefined
console.log(serialize([undefined])); // "["__undef__"]"
console.log(deserialize(serialize([undefined]))) // undefined
console.log(serialize({ undef: undefined })); // {"undef":"__undef__"}
console.log(deserialize(serialize({ undef: undefined }))); // undefined