JSON:从数据到文本的“翻译”艺术
在互联网的世界里,当我们用App刷着朋友圈、用网页查着天气,或是在后台管理着用户信息时,有一个“幕后功臣”始终在默默传递数据——它就是JSON(JavaScript Object Notation,JavaScript对象表示法),但你有没有想过,那些复杂的数据——比如一条包含用户名、年龄、头像和动态的信息——是如何被“打包”成我们看到的简洁文本,又是如何被“拆解”还原的?今天我们就来聊聊:JSON是怎么做成的。
JSON的“前世今生”:为什么需要它?
要理解JSON是怎么做成的,得先知道它“为什么被发明”,在JSON出现之前,计算机之间交换数据主要用XML(可扩展标记语言),XML虽然功能强大,但标签冗余(比如<user><name>张三</name><age>25</age></user>),解析起来麻烦,尤其对于网页这种需要快速加载的场景来说,“体积大、解析慢”成了硬伤。
2002年,一位叫道格拉斯·克罗克福德的程序员觉得:“数据交换应该像写便签一样简单”,他借鉴了JavaScript语言中“对象”的表示方法(用包裹键值对,用[]包裹数组),创造了一种轻量级的数据格式——JSON,它没有复杂的标签,只靠最基础的符号(、[]、、)就能表达数据结构,而且能被JavaScript直接解析,效率极高,很快,JSON就成了互联网数据交换的“通用语言”。
JSON的“配方”:核心结构拆解
JSON的“制作”过程,本质上是将复杂的数据结构“翻译”成符合JSON规范的文本字符串,它的“配方”很简单,只有两种核心结构、六种基本数据类型,外加几个“语法规则”。
两种核心结构:JSON的“骨架”
任何JSON数据,都是由以下两种结构嵌套而成的:
-
对象(Object):用一对花括号表示,存储“键值对”(key-value pair),键(key)必须是字符串(双引号括起来),值(value)可以是任意类型的数据,键和值之间用冒号分隔,多个键值对之间用逗号分隔。
例子:{"name":"张三", "age":25, "isStudent":false}
这里"name"是键,"张三"是值;"age"是键,25是值。 -
数组(Array):用一对方括号
[]表示,存储有序的值列表,值可以是任意类型的数据,多个值之间用逗号分隔。
例子:["苹果", "香蕉", "橙子"]或[{"name":"李四", "age":30}, {"name":"王五", "age":28}]
注意:数组的值也可以是对象,这就是JSON能表达复杂数据的关键——嵌套。
六种基本数据类型:JSON的“食材”
JSON的值(value)只能是以下六种类型,不能是函数、日期等复杂对象(这也是它被称为“轻量级”的原因):
- 字符串(String):用双引号括起来的文本,比如
"hello"、"北京",注意:JSON里不能用单引号! - 数字(Number):整数或小数,比如
100、-3.14,不支持科学计数法(如1e3)。 - 布尔值(Boolean):只有
true和false两个值(全小写,不是True或False)。 - null:表示“空值”或“无值”,比如
"phone":null表示没有电话号码。 - 对象(Object):上面提到的键值对结构。
- 数组(Array):上面提到的有序列表结构。
必须遵守的“语法规则”:JSON的“烹饪准则”
JSON的“制作”就像做菜,食材(数据类型)和骨架(结构)都有了,但必须按“菜谱”(语法规则)来,否则“味道不对”(程序解析时会报错),核心规则有三条:
- 引号必须成对且用双引号:键和字符串值都必须用双引号括起来,单引号是“非法字符”,比如
{name:'张三'}是错的,必须写成{"name":"张三"}。 - 不能有注释:JSON的设计初衷是“纯数据”,没有注释功能(比如
// 这是注释或/* 这是注释 */都会报错)。 - 结尾不能有逗号:最后一个键值对或数组元素后面不能加逗号,比如
{"name":"张三", "age":25,}(25后面多了逗号)或["a", "b", ]("b"后面多了逗号)都是错的。
JSON的“制作过程”:从内存到文本的“旅行”
清楚了JSON的“配方”,接下来就是“制作”过程,假设我们要把一个用户信息从程序内存中“翻译”成JSON字符串,步骤大致如下:
第一步:确定数据结构(设计“蓝图”)
先明确要表达的数据有哪些字段,以及它们之间的关系,比如一个用户信息可能包含:姓名(字符串)、年龄(数字)、是否激活(布尔值)、手机号(字符串,可能为空)、好友列表(数组,每个好友也是一个对象)。
内存中的数据可能是这样的(以Python为例):
user = {
"name": "张三",
"age": 25,
"is_active": True,
"phone": None,
"friends": [
{"name": "李四", "age": 24},
{"name": "王五", "age": 26}
]
}
第二步:按JSON规范“编码”(“翻译”成文本)
程序会按照JSON的语法规则,将内存中的数据逐层“翻译”成文本:
- 最外层是一个对象(用),所以先写。
- 第一个键值对:
"name"(字符串,双引号括起来):"张三"(字符串,双引号括起来),写成"name":"张三",加逗号分隔。 - 第二个键值对:
"age"(数字):25(数字),写成"age":25,加逗号。 - 第三个键值对:
"is_active"(布尔值):True(JSON里用true),写成"is_active":true,加逗号。 - 第四个键值对:
"phone"(空值):None(JSON里用null),写成"phone":null,加逗号。 - 第五个键值对:
"friends"(数组,用[]),数组里有两个对象:- 第一个对象:
{"name":"李四","age":24} - 第二个对象:
{"name":"王五","age":26}
用逗号分隔,写成"friends":[{"name":"李四","age":24},{"name":"王五","age":26}]。
- 第一个对象:
- 所有键值对结束,补上。
最终得到的JSON字符串就是:
{"name":"张三","age":25,"is_active":true,"phone":null,"friends":[{"name":"李四","age":24},{"name":"王五","age":26}]}
第三步:验证与优化(“尝尝咸淡”)
程序会自动检查生成的字符串是否符合JSON语法规则:有没有双引号、有没有多余逗号、数据类型对不对等,如果没问题,这个字符串就可以通过网络发送给其他程序了,为了方便阅读,我们还会手动“格式化”它(加换行和缩进),变成这样:
{
"name": "张三",
"age": 25,
"is_active": true,
"phone": null,
"friends": [
{
"name": "李四",
"age": 24
},
{
"name": "王五",
"age": 26
}
]
}
注意:格式化只是“好看”,不影响数据内容,程序解析时会自动忽略空格和换行。
JSON的“逆过程”:从文本到数据的“解码”
JSON的“制作”不只是“编码”(生成文本),还包括“解码”(解析文本),比如另一个程序收到上面的JSON字符串后,会按相反的“翻译”过程,把它还原成内存中的数据结构:
- 读到,知道是一个对象,开始解析键值对。
- 读到
"name":"张三",把键"name"和字符串值"张三"存入内存对象。 - 读到`"age



还没有评论,来说两句吧...