JSON格式介绍¶
想象一下,您需要把一段信息从一台电脑传递给另一台电脑,或者从一个程序传递给另一个程序。您需要一种双方都能理解的“通用语言”来写这份信息。JSON(JavaScript Object Notation)就是这种“通用语言”之一,而且可能是目前最受欢迎的一种。
JSON的故事其实很简单:它长得像JavaScript里的对象写法,但它是独立于任何编程语言的。就像全世界很多机场都用英语做指示一样,很多软件系统都用JSON来交换数据。
为什么叫“对象表示法”?¶
要理解JSON,先得理解“对象”这个概念。在编程世界里,“对象”就像一张信息卡片,或者一个抽屉。
一个真实的例子:想象一张“联系人卡片”:
- 姓名:张三
- 电话:13800138000
- 城市:北京
- 已婚:是
这张卡片有“属性名”(姓名、电话等)和对应的“值”(张三、13800138000等)。在JSON里,这种“属性名-值”的组合就是最基本的单元。
JSON的核心:用文本表示结构化的数据¶
JSON的核心思想是:用纯文本的方式,来表示有结构的数据。这种结构主要就是两种:对象**和**数组。
对象(Object)—— “带标签的抽屉柜”¶
对象在JSON中用大括号 {} 表示。可以把它想象成一个带标签的抽屉柜:
每个抽屉都有一个**独一无二的标签**(属性名,必须是字符串)
每个抽屉里放着对应的**东西**(值,可以是各种类型)
JSON写法示例:
{
"姓名": "张三",
"电话": "13800138000",
"年龄": 30,
"已婚": true
}
重要规则: - 属性名**必须用双引号**包起来(单引号不行!) - 属性名和值之间用冒号 : 分隔 - 每个属性之间用逗号 , 分隔(最后一个属性后面不要加逗号)
数组(Array)—— “有序的盒子序列”¶
数组在JSON中用中括号 [] 表示。可以把它想象成一排编号的盒子:
盒子有固定的顺序(第一个、第二个、第三个...)
每个盒子可以放任意类型的东西
盒子没有单独的标签,只有位置编号(索引)
JSON写法示例:
["苹果", "香蕉", "橙子", "葡萄"]
数组也可以包含复杂的数据,比如对象:
[
{"水果": "苹果", "价格": 5.8},
{"水果": "香蕉", "价格": 3.2},
{"水果": "橙子", "价格": 4.5}
]
JSON支持的数据类型¶
JSON只能表示有限的几种数据类型,但这几种类型已经足够应对大多数情况:
字符串(String) :用双引号包起来的文本 - 示例:"Hello, World!"、"姓名"、`"123"`(注意:这里的123是文本,不是数字!)
数字(Number) :整数或小数,**不用**引号 - 示例:42、3.14、-10、`1.5e3`(科学计数法,表示1500)
布尔值(Boolean) :表示真或假 - 只有两个值:true`(真)或 `false`(假) - 示例:"已婚": true`
空值(Null) :表示“没有值” - 只有一个值:null - 示例:`"中间名": null`(表示没有中间名)
对象(Object) :前面介绍过,用 {} 表示
数组(Array) :前面介绍过,用 [] 表示
数据类型的重要性 : JSON中的数据类型非常重要,因为接收数据的程序需要知道如何正确处理这些值。比如,数字可以进行数学计算,字符串只能进行文本处理。
一个完整的JSON示例¶
让我们看一个稍微复杂一点的例子,结合了对象、数组和各种数据类型:
{
"公司": "ABC科技有限公司",
"成立年份": 2010,
"是否上市公司": true,
"部门": [
{
"名称": "研发部",
"人数": 50,
"主管": "李四"
},
{
"名称": "市场部",
"人数": 30,
"主管": "王五"
}
],
"地址": {
"城市": "上海",
"街道": "浦东新区张江路123号",
"邮编": "201203"
},
"联系电话": ["021-12345678", "400-888-9999"]
}
这个例子包含了: - 顶层的对象(公司信息) - 字符串(公司名称、部门名称等) - 数字(成立年份、人数) - 布尔值(是否上市公司) - 数组(部门列表、联系电话列表) - 嵌套的对象(地址信息) - 数组中的对象(每个部门的信息)
JSON的“潜规则”:没有注释!¶
这是JSON最让人意外的一点:标准的JSON格式不支持注释。
是的,您没看错。在JSON文件中,您不能像在代码中那样写 // 这是注释 或 /* 这是注释 */。
为什么JSON不支持注释?¶
JSON的设计者道格拉斯·克罗克福德有他的理由: 1. JSON是**数据交换格式**,不是配置文件格式。数据本身不应该携带解释自己的说明。 2. 注释可能被误用,比如包含重要的配置信息,导致解析器需要特殊处理。 3. 保持解析器的简单性。
人们怎么“绕过”这个问题?¶
虽然JSON标准不支持注释,但在实际使用中,人们还是需要注释来解释复杂的数据结构。于是出现了几种变通方法:
方法1:使用特殊的属性名作为“伪注释”¶
{
"_comment": "这是一条注释,通过特殊的属性名实现",
"姓名": "张三",
"_note": "电话号码是必填项",
"电话": "13800138000"
}
优点:简单,所有JSON解析器都能处理。 缺点:注释变成了数据的一部分,可能会被程序误读。
方法2:使用JSON5(JSON的扩展)¶
JSON5是JSON的扩展,添加了很多便利特性,其中就包括注释:
{
// 这是一行单行注释
"姓名": "张三",
/*
这是一个
多行注释
*/
"电话": "13800138000",
年龄: 30, // 属性名可以不用引号(在JSON5中)
'地址': '北京', // 允许使用单引号
已婚: true,
孩子: null
}
JSON5的主要扩展特性:
支持单行注释(//)和多行注释(/* */)
属性名可以不用引号(如果没有特殊字符)
允许尾随逗号(数组或对象的最后一个元素后面可以加逗号)
字符串可以用单引号
数字可以写成十六进制、有前导小数点等
注意:JSON5不是标准JSON,需要使用支持JSON5的解析器才能正确读取。
方法3:在数据处理前移除注释¶
一些工具链会在处理JSON文件前,先用预处理器移除所有注释。这样开发者可以在源文件中写注释,但最终传输或存储的是没有注释的标准JSON。
JSON的优缺点¶
优点:¶
人类可读:相比于XML,JSON更简洁,更容易被人眼阅读和理解。
机器友好:几乎所有编程语言都有成熟的JSON解析库,处理起来非常高效。
轻量级:没有像XML那样的冗余标签,文件体积相对较小。
结构清晰:对象和数组的嵌套可以表示复杂的数据结构。
广泛支持:已成为Web API的事实标准,绝大多数网络服务都使用JSON。
缺点:¶
没有注释:如上所述,标准JSON不支持注释。
数据类型有限:没有日期时间类型(通常用字符串表示)、没有二进制数据类型。
严格的语法:一个多余的逗号、一个缺失的双引号都会导致整个文件解析失败。
不支持循环引用:不能表示A引用B,B又引用A这样的数据结构。
JSON与相似格式的比较¶
特性 |
JSON |
YAML |
XML |
CSV |
|---|---|---|---|---|
主要用途 |
数据交换、配置 |
配置、数据序列化 |
文档标记、数据交换 |
表格数据交换 |
可读性 |
很好 |
极好 |
一般(冗余标签多) |
好(简单表格) |
注释支持 |
不支持 |
支持 |
支持 |
有限支持 |
数据类型 |
基本类型+对象+数组 |
丰富类型 |
只有文本(类型需额外定义) |
只有文本 |
语法严格度 |
非常严格 |
严格(对缩进敏感) |
严格 |
相对宽松 |
文件大小 |
较小 |
较小 |
较大 |
最小 |
学习曲线 |
平缓 |
中等 |
中等 |
平缓 |
什么时候应该使用JSON?¶
使用JSON的场景:¶
Web API:前后端通信、微服务之间的数据交换。
配置文件:很多现代软件用JSON作为配置文件格式(如VS Code的settings.json)。
数据存储:NoSQL数据库(如MongoDB)使用类JSON的格式存储数据。
日志记录:结构化的日志信息。
消息队列:在系统间传递结构化的消息。
### 不应该使用JSON的场景:¶
需要大量注释的配置:考虑使用YAML或TOML。
处理二进制数据:考虑使用专门的二进制格式。
需要复杂文档结构:考虑使用XML(如Office文档)。
简单的键值对配置:考虑使用INI或环境变量。
实际应用中的小技巧¶
1. 格式化与验证¶
JSON对格式要求严格,以下工具可以帮助您: - 格式化工具:让压缩在一行的JSON变得易读(很多在线工具和编辑器插件)。 - 验证工具:检查JSON语法是否正确(如[jsonlint.com](https://jsonlint.com))。
2. JSON Schema¶
如果您需要定义JSON数据的结构(哪些字段是必需的、字段的类型等),可以使用JSON Schema。它本身也是用JSON写的,用来描述和验证JSON数据的结构。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"姓名": {
"type": "string"
},
"年龄": {
"type": "number",
"minimum": 0
}
},
"required": ["姓名"]
}
这个Schema定义了一个对象,必须有"姓名"字段(字符串类型),可以有"年龄"字段(数字类型,最小值为0)。
3. 处理JSON的程序代码示例¶
几乎每种编程语言都能轻松处理JSON:
Python示例:
import json
# 将Python字典转换为JSON字符串
data = {"姓名": "张三", "年龄": 30}
json_string = json.dumps(data, ensure_ascii=False, indent=2)
print(json_string)
# 将JSON字符串解析为Python字典
parsed_data = json.loads(json_string)
print(parsed_data["姓名"]) # 输出:张三
JavaScript示例:
// 将JavaScript对象转换为JSON字符串
let data = {姓名: "张三", 年龄: 30};
let jsonString = JSON.stringify(data, null, 2);
console.log(jsonString);
// 将JSON字符串解析为JavaScript对象
let parsedData = JSON.parse(jsonString);
console.log(parsedData.姓名); // 输出:张三
总结¶
JSON是一种简洁、高效、通用的数据交换格式。它的核心是两种结构: 对象 (带标签的键值对集合)和**数组**(有序的值列表),配合几种基本数据类型(字符串、数字、布尔值、null)。
虽然JSON不支持注释这一点常常让人感到不便,但这也促使它保持了简单性和一致性。在实际应用中,您可以通过添加特殊字段、使用JSON5扩展,或在工具链中预处理等方式来解决注释问题。
无论您是开发Web应用、编写配置文件,还是在不同系统间传递数据,JSON都是一个可靠的选择。它已经成为了现代软件开发中不可或缺的一部分,就像螺丝钉和胶水一样,虽然不起眼,但却无处不在,连接着数字世界的各个部分。
最后的小测试 :如果您看到这样的文本,能认出它是JSON吗?
{"quiz": {"问题": "JSON是什么?", "答案": "一种数据交换格式"}}
是的,这就是一个合法的JSON对象!现在您已经了解了它的基本规则。