【问题标题】:Besides Set and Map, what other common JS classes do not play nice with JSON.stringify()?除了 Set 和 Map,还有哪些常见的 JS 类不适合 JSON.stringify()?
【发布时间】:2019-10-01 07:24:40
【问题描述】:

当我们在 Map 或 Set 上调用 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 输出中的字符串,因此当您解析 JSON 时,您仍然只有字符串。
  • 似乎问题的区别在于产生有用与无用 JSON 序列化的类。
  • 从此answerDates、函数、undefinedInfinity、RegExps、Maps、Sets、Blobs、FileLists、ImageDatas、稀疏数组、类型化数组和其他复杂的类型。
  • 是的,这就是我的意思是接收者需要知道将其转换回来。 JSON 的大部分价值在于自动翻译成一种语言类型。

标签: javascript node.js ecmascript-6


【解决方案1】:

JSON 仅支持:字符串、数字、布尔值、null 和数组以及带有这些值/属性的普通对象。而已。因此,没有任何其他类型的对象由 JSON 直接支持。

您必须手动将您的对象转换为可以用 JSON 中的这些基本类型表示的东西,或者找到其他方式来表示您的对象。对象中的数据(如具有简单值/索引的 Map)可以手动放入 JSON 格式(可能在对象数组或数组数组中),但是在反序列化时将其转换回 Map 必须手动完成。

您可以在此处查看 JSON 支持的类型:https://www.json.org/

这意味着没有自定义对象类型,即使其实例数据仅由上述类型组成,也会反序列化为正确的对象类型。这甚至包括DateRegex 之类的东西,当然也包括任何非普通对象,例如SetMap

可以手动将您的数据转换为 JSON 可序列化的内容,然后手动反序列化为适当的对象。例如,您可以序列化仅包含合法键和值的非嵌套 MapSet,如下所示:

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 属性来标识要调用的适当类名。当然,源和目标都必须具有适当的序列化和反序列化扩展才能使其正常工作。

【讨论】:

    猜你喜欢
    • 2014-09-19
    • 2023-03-15
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 2023-02-13
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多