一句话概括
JSON 是一种基于文本的方式,可以像列表或字典一样组织数据,让计算机和人类都能极其轻松地读取、编写和交换信息。
它解决的问题
想象一下 21 世纪初的互联网。如果你想让你的网页在不重新加载整个页面的情况下获取新数据(一个叫做 AJAX 的热门新概念),你可能得跟 XML “搏斗”。XML(可扩展标记语言)是当时数据交换领域的卫冕冠军。它功能强大,语法严格,而且……说实话,有点臃肿。
一个 XML 文档非常冗长。每一条数据都被包裹在开始和结束标签里。
<user>
<id>123</id>
<name>Alex</name>
<isAdmin>true</isAdmin>
</user>
这还不算太糟,但就是有点笨重。更重要的是,在浏览器语言 JavaScript 中解析它简直是场噩梦。你必须在一个复杂的文档对象模型(DOM)中导航,处理节点、属性和文本内容。感觉就像杀鸡用牛刀。
这时,Douglas Crockford 出现了,他当时在一家后来成为 Yahoo! 的公司工作。他发现了一个绝妙的点子:JavaScript 本身就有一种非常好的、内置的方式来定义结构化数据。它被称为“对象字面量表示法”。
// 这就是纯粹的 JavaScript!
var user = {
"id": 123,
"name": "Alex",
"isAdmin": true
};
Crockford 意识到,这个 JavaScript 语法的子集本身就是一种极佳的数据格式。它轻量、易于人类阅读,而且——这是它的杀手级特性——对于 JavaScript 来说解析起来简直不费吹灰之力。你基本上可以直接 eval() 它(尽管出于安全原因,我们现在使用像 JSON.parse() 这样更安全的方法)。
他将这种格式规范化,给它取名为 JavaScript Object Notation (JSON),并创建了一个简单的单页网站来解释它。它解决了一个问题:我们需要一种比 XML 更轻量、并且原生于 Web 环境的数据格式。JSON 如野火般蔓延开来,成为 API、配置文件和无数其他应用事实上的标准语言。它之所以能赢,是因为它简单、实用,并且源于它所要服务的那门语言。
底层工作原理
JSON 的核心就是一套将数据写成文本的规则。把它想象成数据结构的通用蓝图。它只有两种组织结构的方式和六种可以放入其中的简单数据类型。
基本构建块:数据类型
JSON 的优雅之处在于其极简的值类型集合。JSON 中的一切都是这些类型之一。
| 类型 | 示例 | 描述 |
|---|---|---|
| String (字符串) | "Hello, world!" |
一串 Unicode 字符,用双引号包裹。 |
| Number (数字) | 42, -3.14, 2.99e8 |
整数或浮点数。没有 NaN 或 Infinity。 |
| Boolean (布尔值) | true, false |
逻辑上的真和假,始终为小写。 |
| Null (空值) | null |
表示有意设置的空值,始终为小写。 |
| Array (数组) | [1, "two", false] |
一个有序的值列表,用方括号 [] 括起来。 |
| Object (对象) | {"key": "value"} |
一个无序的键值对集合,用花括号 {} 括起来。 |
就这些。没有日期、没有函数、没有特殊类型。这种简洁性是一种特性,而不是缺陷,因为它保证了数据几乎可以被任何编程语言所理解。
结构:对象和数组
真正的魔法发生在你组合这些基本构建块的时候。
对象用于当你有一组命名的东西时。其中的“键”(名称)必须是放在双引号里的字符串。“值”可以是六种数据类型中的任意一种,包括另一个对象或数组。这就是你创建层级结构的方式。
数组用于当你有一个有序的东西列表时。顺序很重要,你可以通过它们的位置(索引,从零开始)来访问项目。
让我们来构建一个简单的用户个人资料。它是一个对象,因为它有像 name 和 email 这样的命名属性。其中一个属性 skills 是一个列表,所以我们使用数组。
{
"userId": "u-9a8b7c",
"username": "CodeWizard",
"isActive": true,
"lastLogin": null,
"profile": {
"realName": "Dana Scully",
"location": "Washington, D.C."
},
"skills": [
"Forensic Pathology",
"Firearms",
"Rational Skepticism"
]
}
看到嵌套了吗?一个对象(profile)是主对象内部的一个值。一个数组(skills)是另一个值。这种树状结构可以根据需要进行任意深度的嵌套,让你能够模拟极其复杂的数据。
在 JavaScript 中,访问这些数据非常直观:
data.username 会得到 "CodeWizard"。
data.profile.realName 会得到 "Dana Scully"。
data.skills[0] 会得到 "Forensic Pathology"。
这种与原生语言结构的直接映射正是开发者喜爱它的原因。
语法规则
要成为一个有效的 JSON,你必须遵守一些严格的规则。正是这种严格性使其能够被机器可靠地解析。
- 只能用双引号: 所有的键和所有的字符串值都必须用双引号(
")括起来。单引号(')是语法错误。 - 不能有尾随逗号: 逗号用于分隔数组中的元素或对象中的键值对。你不能在最后一个元素后面加逗号。
// 错啦!'true' 后面多了个逗号 { "key1": "value1", "key2": true, } - 对象和数组: 数据通过对象(
{})或数组([])来组织。一个有效的 JSON 文档可以是一个单一的值(比如字符串"hello"),但顶层容器几乎总是一个对象或数组。 - 空白字符很灵活: 在字符串之外的空格、制表符和换行符都无所谓。这使得既可以有用于人类阅读的“漂亮”缩进格式,也可以有用于高效网络传输的“压缩”单行格式。
真实世界的应用案例
社交媒体信息流
前端开发者 Maya 的任务是为一个新的社交网络构建无限滚动的信息流。每当用户滚动到页面底部附近时,她的 JavaScript 代码就需要向服务器请求更多的帖子。服务器返回的不是 HTML,而是纯数据。它发送一个 JSON 数组,其中每个元素都是一个代表帖子的对象。这个对象包含帖子的文本、作者的用户名、头像链接、点赞数,甚至还有一个包含前几条评论的嵌套数组。Maya 的代码接收到这个干净的 JSON,遍历数组,然后动态创建每个帖子的 HTML,并将其附加到页面上。
经验之谈: JSON 是现代动态 Web 应用的生命线,充当了服务器大脑和浏览器表示层之间的轻量级信使。
游戏配置
独立游戏开发者 Leo 正在创作一款角色扮演游戏。他需要管理成百上千的物品:剑、药水、盔甲等等。如果将每个物品的属性(名称、伤害、重量、价格)直接硬编码到游戏的 C++ 代码中,那么在平衡和更新时将是一场噩梦。于是,他创建了一个 items.json 文件。这是一个巨大的 JSON 对象,其中每个键都是一个物品 ID(比如 "longsword"),值是另一个包含其所有属性的对象。游戏开始时,它会读取这个文件并将所有物品数据加载到内存中。为了重新平衡游戏,他只需要编辑这个文本文件,无需重新编译。
经验之谈: JSON 是配置文件的一种绝佳格式,它将应用程序的数据与其逻辑分离,并使其易于被人类编辑。
微服务交响曲
后端工程师 Fatima 在一个由几十个微服务组成的系统上工作。一个“用户服务”管理用户账户,一个“订单服务”管理购买,还有一个“通知服务”发送电子邮件。当用户下订单时,订单服务需要确认用户的收货地址。它不直接查询数据库,而是向用户服务的 API 端点发出 HTTP 请求,比如 GET /api/users/123/address。用户服务返回一个简单的 JSON 对象:{"street": "123 Main St", "city": "Anytown"}。订单服务解析这个 JSON,验证订单,然后向通知服务发送一个请求(同样带有 JSON 负载)来发送收据邮件。
经验之谈: 在一个分布式系统中,JSON 充当了一种通用的、与语言无关的契约,使得用 Go、Python 和 Node.js 编写的服务能够无缝地相互通信。
常见错误和陷阱
- 尾随逗号: 这是最常见的验证错误。JavaScript 的数组和对象通常更宽容,但 JSON 是严格的:集合中的最后一个元素后面不能有逗号。
- 注释: JSON 没有注释。句号。习惯了
//或/* */的开发者经常试图添加注释,但这会立即使 JSON 无效。“官方”的奇技淫巧是添加一个像"_comment": "你的注释写在这"这样的键,解析器会将其视为另一条数据。 - 单引号 vs. 双引号: 所有的键和所有的字符串都必须使用双引号(
")。如果你是从 Python 字典或某些 JavaScript 风格指南过来的,你可能习惯用单引号,但在 JSON 中这是禁止的。 undefined这玩意儿不存在: 在 JavaScript 中,一个缺失的对象属性是undefined。JSON 没有这个概念。要表示一个缺失或空的值,你必须明确使用null。- 未转义的引号: 如果你的字符串值需要包含一个双引号,你必须用反斜杠(
\)来转义它。忘记这一点({"quote": "She said "Hello""})会破坏结构。正确的方式是{"quote": "She said \"Hello\""}。
为什么你应该关注它
在现代软件开发中,JSON 不仅仅是“值得关注”;它就是行业标准。它在如此多关键任务中都是默认格式,以至于不熟悉它就像一个不知道盐是什么的厨师。
无论何时,只要你遇到以下情况,都应该首先想到 JSON:
- 你正在构建或使用一个 Web API。
- 你需要一个应用程序的配置文件。
- 你需要将结构化数据存储在一个简单的文本文件或像 MongoDB 这样的 NoSQL 数据库中。
- 你正在从服务器端进程向客户端 JavaScript 应用程序发送数据。
- 你需要一种简单、人类可读的格式来序列化一个对象,以便通过网络发送或保存到磁盘。
基本上,如果你需要让两个不同的程序相互交谈,或者你需要将数据与代码分离,JSON 几乎总是你的首选最佳答案。
深入了解
- JSON.org:由 Douglas Crockford 编写的原始单页规范。一份简洁文档的杰作。
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format:官方、正式的互联网标准。内容密集但具有权威性。
- MDN Web Docs: JSON:一份非常出色且实用的 Web 开发者指南,重点介绍了 JavaScript 内置的
JSON对象。(链接已本地化为中文版) - Wikipedia: JSON:用于宏观了解其历史、替代方案及其在编程世界中的作用。
- Google TechTalks: The JSON Saga:Douglas Crockford 本人讲解 JSON 背后历史和设计理念的视频。观看过程有趣且富有洞见。