什么是 JSON?
JSON(JavaScript Object Notation,RFC 8259)是一种轻量级的、与语言无关的数据交换格式。它用极简的文本描述结构化数据,既能让人直接读懂,又能被几乎所有编程语言以极低成本解析。今天你打开的每一个 App、调用的每一个 REST API、写入的每一个 NoSQL 文档,背后几乎都在用 JSON 传递数据。
JSON 之所以能击败 XML 成为 Web 时代的事实标准,核心原因只有三个:够简单(六种类型覆盖绝大多数场景)、够严格(没有歧义,解析结果可预测)、够通用(从浏览器到嵌入式设备都有原生支持)。
JSON 的六种数据类型
理解 JSON 的第一步,是记住它只有六种值类型,不会有第七种:
| 类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | "oltool" |
必须用双引号包裹,支持 \n、\t、\uXXXX 等转义 |
| 数字 | 42、3.14、-0.5 |
不区分整数与浮点,统一按双精度处理 |
| 布尔 | true / false |
小写,不是字符串 |
| 空值 | null |
表示"有值但为空",区别于"字段不存在" |
| 对象 | {"k": "v"} |
无序的键值对,键必须是字符串 |
| 数组 | [1, 2, 3] |
有序的值列表,元素可以是任意类型 |
一个真实世界里的 JSON 往往同时包含这些类型:
{
"user": {
"id": "u_1001",
"name": "彬哥",
"active": true,
"roles": ["admin", "editor"],
"metadata": null
},
"score": 98.5
}
嵌套结构:对象与数组的组合
JSON 的强大之处在于对象可以嵌套对象、数组可以嵌套数组、对象和数组还能互相嵌套。这种组合足以表达任意复杂度的业务数据,而语法始终保持一致:
- 用对象表达"一条记录的属性"。
- 用数组表达"一组同构的元素"。
- 用对象数组表达"一张表"(最常见的 API 返回形态)。
当层级过深时,人的肉眼很难看清结构。开发时建议先用 JSON 格式化 工具把压缩的一行展开成带缩进的树,或用 JSON 树形查看器 折叠浏览;需要把后端返回的大文档转成表格分析时,可以用 JSON 转 CSV。
典型用法:API、配置与存储
1. 接口数据交换。 这是 JSON 的主战场。请求体、响应体、Webhook 回调几乎都是 JSON。它的严格类型让前后端"说什么就是什么",不需要像 XML 那样先约定 schema 才能解析。
2. 配置文件。 从 package.json 到 tsconfig.json,Node 生态把 JSON 当成默认的声明格式。需要人工频繁编辑的配置则更常写成 YAML,再在构建期转成 JSON 给程序消费——可借助 YAML 转 JSON 与 JSON 转 YAML 互转。
3. 文档型存储。 MongoDB、DynamoDB、RedisJSON 等直接用 JSON 文档建模数据,字段可以随记录灵活增减,特别适合 schema 演进快的场景。
与 XML / YAML / MessagePack 的取舍
| 维度 | JSON | XML | YAML | MessagePack |
|---|---|---|---|---|
| 可读性 | 好 | 一般 | 最好 | 差(二进制) |
| 解析速度 | 快 | 慢 | 慢 | 最快 |
| 注释支持 | 否 | 是 | 是 | 否 |
| 体积 | 中 | 大 | 中 | 最小 |
| 典型场景 | API / 存储 | 遗留系统 / SOAP | 人工配置 | 高性能二进制传输 |
结论很直接:机器之间高频交换选 JSON,人工写的配置选 YAML,极限性能/带宽场景选 MessagePack(底层仍是 JSON 的语义)。XML 如今主要在银行、电信等遗留系统里出现,新项目很少主动选择。
高频踩坑点(务必注意)
1. 大数精度丢失
这是最隐蔽、最致命的坑。JSON 没有整数类型,所有数字都按 IEEE 754 双精度浮点解析。超过 2^53(约 9007 万亿)的整数无法被精确表示——典型受害者是 64 位雪花 ID、数据库自增主键、身份证号。一旦在 JavaScript 里 JSON.parse,大整数会被悄悄四舍五入成近似值,且不会报错。
防御:跨语言传输大整数时优先用字符串;前端需要用 JSON.parse 的 reviver 配合 BigInt,或使用支持大数的解析库。
2. 末尾逗号与引号
JSON 比 JavaScript 严格:对象/数组最后一个元素后面不能有逗号,键必须用双引号(单引号非法),字符串内部的双引号必须转义为 \"。这些在浏览器控制台里能跑的写法,到了标准 JSON 解析器里全部报错。
3. 字符串里的换行与不可见字符
从 Excel、 Word 或网页文本框复制进 JSON 的多行文本,常常夹带真实的换行符、制表符或 BOM。标准 JSON 要求字符串里的换行必须写成 \n,原始换行会直接让解析失败。提交前用格式化工具做一次清洗和校验能省掉大量调试时间。
4. 循环引用与函数
JSON.stringify 遇到循环引用的对象会直接抛 TypeError;它也会自动丢弃函数、undefined 和 Symbol。如果你的数据里混入了这些类型,序列化结果会和预期悄悄不一致——尤其是把前端状态整体转 JSON 时极易中招。
5. JSON 注入
把不可信的用户输入直接拼进 JSON 字符串(而不是用 JSON.stringify),或在前端用 eval / JSON.parse 解析来路不明的字符串,都可能引发注入。始终用标准序列化/解析 API,并对外部输入做校验。
现代工作流建议
- 写:用 TypeScript 时,把示例 JSON 直接喂给 JSON 转 TypeScript 生成接口类型,避免手敲 schema 出错。
- 查:用 JSONPath 查询 从深层文档里精确提取字段,比肉眼翻层级高效得多。
- 验:上线前用 JSON 格式化/校验 跑一遍,定位语法错误的具体行列号。
- 换:跨格式用 JSON 转 XML、JSON 转 TOML、Excel 转 JSON 等工具批量转换,不必手写脚本。
所有这些操作都能在码屋(Mawu)的在线工具里本地完成——数据只存在于你的浏览器,不上传任何服务器,断网也能用。
小结
JSON 看似简单,却是现代软件最重要的"通用语"。掌握它的六种类型与嵌套规则只是起点,真正拉开差距的是对精度陷阱、严格语法、注入风险的警惕。把它当成一个需要被尊重和校验的契约,而不是随手拼的字符串,你的接口和配置会少掉一大类诡异 bug。