除了Set和Map,还有哪些其他常见的JS类不能与JSON.stringify()配合使用?
[当我们在地图或集合上调用JSON.stringify时,我们得到的数据为空:
console.log(JSON.stringify({foo: new Map([[1,2], [3,4]])}));
我们刚得到:
{"foo":{}}
我可以使用以下方式或多或少地解决上述问题:
console.log(JSON.stringify({foo: Array.from(new Map([[1,2], [3,4]]))}));
但是我的问题是-除了Map和Set之外,还有其他没有自动序列化的核心JS类吗?
回答如下:JSON仅支持:字符串,数字,布尔值,null和数组以及带有值/属性的简单对象。而已。因此,除了JSON直接支持的对象之外,没有其他类型的对象。
您必须手动将对象转换为可以用JSON中的这些基本类型表示的对象,或者找到其他表示对象的方法。可以简单地将对象(例如具有简单值/索引的Map)中的数据放入JSON形式(也许以对象数组或数组数组的形式),但是在反序列化时将其转换回Map则必须手动完成。
您可以在此处查看JSON支持的类型:https://www.json/
这意味着没有自定义对象类型,即使其实例数据仅由上述类型组成,也会反序列化为正确的对象类型。这甚至包括Date
或Regex
之类的东西,当然还包括诸如Set
或Map
之类的任何非普通对象。
可以将您的数据手动转换为JSON可序列化的内容,然后手动将其反序列化为适当的对象。例如,您可以序列化仅包含合法键和值的非嵌套Map
和Set
:
function serialize(mapOrSet) { if (mapOrSet instanceof Map) { // convert Map into 2D array // [[key1, val1], [key2, val2], ....] let data = []; for (const [key, value] of mapOrSet) { data.push([key, value]); } return JSON.stringify({ _customType: "Map", _data: data }); } else if (mapOrSet instanceof Set) { return JSON.stringify({ _customType: "Set", _data: Array.from(mapOrSet); }); } else { throw new TypeError("argument to serialize() must be Map or Set"); } }
然后,您必须具有一个自定义反序列化器,该自解序列器可以检测具有
_customType
属性的对象,并调用适当的解序列器函数以将纯JSON转换为适当的自定义对象类型。您甚至可以通过使用某种_customType
属性来标识要调用的适当的类名称,使对象支持它们自己的序列化和反序列化功能,从而使系统可扩展。当然,源和目标都必须具有适当的序列化和反序列化扩展,才能使其正常工作。