JSON 支持的的数据格式
JSON
前言
目前 JSON
现在已经成为了前后端前后端交换数据的最常用格式,作为一个前端开发,每天都离不开它。
但针对 JSON,我们还有一些不明白或应该避开的坑在里面。
JSON 是什么
MDN 文档中可以查询到:
JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null。
JSON 支持的数据类型
通过定义我们可以了解到,JSON 中支持对象,数组,数字,字符串,布尔值,和 null。 这样在说明太宽泛,针对每一种类型,下面说明 JSON 的支持情况也具体怎么样。
一. JSON 支持格式:对象
对象是一个比较宽泛的概念,JSON 支持的对象,只包含一般的键值对,键值对的属性名只能是字符串,需要用双引号包裹。不包含 JavaScript 中的不可遍历属性。对象中的值也只能包含数组、数字、字符串、布尔值、null,以另一个对象,不可进行对象的嵌套引用。例:
{
"a": {
"b": "JSON 支持格式"
}
}
二. JSON 支持格式:数组
数组中的值也只能包含 JSON 支持的值数组、数字、字符串、布尔值、null、对象。不会包含 length 等不可遍历的其他属性。例:
{ "a": [1, 2, "JSON 支持格式"] } // 可以放在对象
[1, 2, "JSON 支持格式"] // 可以单独存在
[1, [2, 3], { "a": 120 }] // 数组中可以包含对象和其他数组
三. JSON 支持格式:数字
只能是10进制的双精度浮点型数字,支持科学计数法,二进制、八进制、十六进制统统不支持。也不支持 BigInt,所以在针对一些数字类型的 ID 要特别注意,要前后端沟通好长度问题或以字符串格式传输,不然可能会损失精度导致问题。例:
{ "a": 120 } // 一般数字
{ "a": 1.2E3 } // 科学计数法
特别注意:JSON 不支持 NaN 和正负 Infinity
四. JSON 支持格式:字符串
例:
{ "a": "" } // 支持空字符串
{ "a": "JSON 支持格式" }
五. JSON 支持格式:布尔值
支持 true 和 false
六. JSON 支持格式:null
null 在 JSON 中是被支持的,注意 JSON 并不支持 JavaScript 中常用的 undefined,用 JSON 序列化 undefined 时,对应的键会被删除。例:
{ "a": null } // 支持 null
{ "a": undefined } // 这是不支持的
// JavaScript 中执行 JSON.stringify({a: undefined}) 时得到空对象
{}
JSON 不支持的数据类型(只列举常见部分)
一. 特殊值
不支持 undefined、NaN、-Infinity、Infinity 等
二. 不支持 Symbol、BigInt
Symbol、BigInt 目前也不支持,BigInt 可以尝试转为字符串进行传输。
三. 其他一些非一般键值对对象
-
Date 日期对象并不能得到 JSON 的支持,但是我们经常把 Date 对象直接放进数据中传输,这是因为在 Date 有一个
toJSON()
方法,会按国际标准进行日期的序列化,生成固定格式的字符串,序列化后的日期字符串便于识别,并便于重新生成 Date 对象。例:const dateString = JSON.stringify(new Date()) console.log(dateString) // "2021-10-29T02:24:40.552Z"
但直接对序列化后的日期字符串进行
JSON.parse(dateString)
操作并不可行。但可以用new Date(dateString)
生成新的日期对象。 -
Set 对象并不能直接进行
JSON.stringify()
进行处理,我们需要把它变成一般数组对象后进行序列化处理。JSON.stringify(new Set([1, 2, 3])) // 会得到一个序列化后的空对象 "{}" JSON.stringify(Array.from(new Set([1, 2, 3]))) // "[1,2,3]"
-
Map 也同理,例:
JSON.stringify(new Map([['a', 12132], ['b', 'daf121']])) // "{}" JSON.stringify(Object.fromEntries(new Map([['a', 12132], ['b', 'daf121']]))) // `{"a":12132,"b":"daf121"}`
-
其他 JS 对象也都基本不能直接进行 JSON.序列化的,但针对一个对象,如果我们需要对它进行 JSON 序列化,但我们并不想对他每次都进行特殊处理,有什么办法吗?答案是有的,
JSON.stringify()
实际会跑一个对象的 toJSON() 方法,我会给一个对象添加 toJSON() 方法,就可以愉快地进行JSON.stringify()
序列化了。例:Map.prototype.toJSON = function () { return JSON.stringify(Object.fromEntries(this)) } // 给 Map 原型添加 toJSON 方法 JSON.stringify(new Map([['a', 12132], ['b', 'daf121']])) // 这样就可以正常打印出内容了 '{"a":12132,"b":"daf121"}'
lithoge (作者) 2021-10-17 09:35:37
dfkajk
lithoge (作者) 2021-10-17 09:35:57
@lithogefdkajfkdka