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只能表示有限的几种数据类型,但这几种类型已经足够应对大多数情况:

  1. 字符串(String) :用双引号包起来的文本 - 示例:"Hello, World!""姓名"`"123"`(注意:这里的123是文本,不是数字!)

  2. 数字(Number) :整数或小数,**不用**引号 - 示例:423.14-10`1.5e3`(科学计数法,表示1500)

  3. 布尔值(Boolean) :表示真或假 - 只有两个值:true`(真)或 `false`(假) - 示例:"已婚": true`

  4. 空值(Null) :表示“没有值” - 只有一个值:null - 示例:`"中间名": null`(表示没有中间名)

  5. 对象(Object) :前面介绍过,用 {} 表示

  6. 数组(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的优缺点

优点:

  1. 人类可读:相比于XML,JSON更简洁,更容易被人眼阅读和理解。

  2. 机器友好:几乎所有编程语言都有成熟的JSON解析库,处理起来非常高效。

  3. 轻量级:没有像XML那样的冗余标签,文件体积相对较小。

  4. 结构清晰:对象和数组的嵌套可以表示复杂的数据结构。

  5. 广泛支持:已成为Web API的事实标准,绝大多数网络服务都使用JSON。

缺点:

  1. 没有注释:如上所述,标准JSON不支持注释。

  2. 数据类型有限:没有日期时间类型(通常用字符串表示)、没有二进制数据类型。

  3. 严格的语法:一个多余的逗号、一个缺失的双引号都会导致整个文件解析失败。

  4. 不支持循环引用:不能表示A引用B,B又引用A这样的数据结构。

JSON与相似格式的比较

JSON与其他格式的简单比较

特性

JSON

YAML

XML

CSV

主要用途

数据交换、配置

配置、数据序列化

文档标记、数据交换

表格数据交换

可读性

很好

极好

一般(冗余标签多)

好(简单表格)

注释支持

不支持

支持

支持

有限支持

数据类型

基本类型+对象+数组

丰富类型

只有文本(类型需额外定义)

只有文本

语法严格度

非常严格

严格(对缩进敏感)

严格

相对宽松

文件大小

较小

较小

较大

最小

学习曲线

平缓

中等

中等

平缓

什么时候应该使用JSON?

使用JSON的场景:

  1. Web API:前后端通信、微服务之间的数据交换。

  2. 配置文件:很多现代软件用JSON作为配置文件格式(如VS Code的settings.json)。

  3. 数据存储:NoSQL数据库(如MongoDB)使用类JSON的格式存储数据。

  4. 日志记录:结构化的日志信息。

  5. 消息队列:在系统间传递结构化的消息。

### 不应该使用JSON的场景:

  1. 需要大量注释的配置:考虑使用YAML或TOML。

  2. 处理二进制数据:考虑使用专门的二进制格式。

  3. 需要复杂文档结构:考虑使用XML(如Office文档)。

  4. 简单的键值对配置:考虑使用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对象!现在您已经了解了它的基本规则。