8.5 KiB
JSON(全称 JavaScript Object Notation)是一种轻量级的数据交换格式。
简单来说,JSON 就是一种文本格式,用来在不同的程序、不同的编程语言、或者客户端与服务器之间传递数据。虽然它的名字里带有 "JavaScript",但它其实是独立于语言的。几乎所有的现代编程语言(C++, Python, Java, Go 等)都支持解析和生成 JSON。
1. JSON 的核心结构
JSON 的结构非常简单,只有两种基本结构:
- 对象 (Object):无序的键值对集合(类似于 C++ 的
std::map或 Python 的dict)。 - 数组 (Array):有序的值的列表(类似于 C++ 的
std::vector或 Python 的list)。
2. JSON 的语法规则(非常严格!)
很多初学者容易把 JavaScript 对象字面量和 JSON 搞混,JSON 的语法要严格得多:
- 数据在键值对中:
"key": value - 数据由逗号分隔:最后一个元素后面不能有逗号(虽然部分解析器允许,但标准不允许)。
- 花括号保存对象:
{ ... } - 方括号保存数组:
[ ... ] - 字符串必须用双引号:这是最容易出错的地方。必须是
",不能是单引号'。Key(键)也必须用双引号包围。
3. JSON 支持的数据类型
JSON 的值(Value)只能是以下 6 种数据类型:
| 类型 | 描述 | 示例 |
|---|---|---|
| String | 字符串 | "Hello World" (必须双引号) |
| Number | 数字 | 100, -5.5, 3.14 (不分整型浮点) |
| Boolean | 布尔值 | true, false (全小写) |
| Null | 空值 | null (表示空) |
| Object | 对象 | {"id": 1} (嵌套结构) |
| Array | 数组 | [1, 2, 3] |
注意:JSON 不支持函数、日期(通常转为字符串)、undefined 或注释。
4. 一个完整的 JSON 示例
假设我们要描述一个“程序员”的信息,JSON 文件可能长这样:
{
"name": "张三",
"age": 28,
"isEmployee": true,
"skills": ["C++", "Python", "Linux"],
"address": {
"city": "上海",
"street": "南京东路",
"zipcode": null
},
"projects": [
{
"name": "后台管理系统",
"status": "completed"
},
{
"name": "AI 助手",
"status": "developing"
}
]
}
解析上面的内容:
- 最外层是一个 Object
{}。 "name"是键,值是字符串"张三"。"age"是键,值是数字28。"skills"是键,值是一个 Array[],里面包含三个字符串。"address"是键,值是一个嵌套的 Object{}。"zipcode"的值是null。
5. 常见应用场景
- 前后端通信:
- 前端(网页/App)向服务器请求用户数据,服务器查询数据库后,将数据组装成 JSON 格式返回给前端。
- 配置文件:
- 很多软件使用
.json文件来存储配置(如 VS Code 的settings.json)。
- 很多软件使用
- 数据存储:
- NoSQL 数据库(如 MongoDB)直接以类似 JSON 的格式(BSON)存储数据。
6. JSON 与 C++ (结合你上一个问题)
在 C++ 中,标准库没有内置 JSON 解析器,通常使用第三方库(最著名的是 nlohmann/json)。
JSON 和 std::variant 的关系非常紧密。因为 JSON 的值可能是数字、字符串、布尔值等多种类型中的一种,解析 JSON 的底层实现往往就是基于 std::variant 或者类似的联合体机制。
例如,一个简易的 JSON Value 类在 C++ 中可能这样定义:
#include <variant>
#include <string>
#include <vector>
#include <map>
struct JsonValue; // 前向声明
// 定义 JSON 支持的类型
using JsonVariant = std::variant<
std::nullptr_t,
bool,
double,
std::string,
std::vector<JsonValue>, // 数组
std::map<std::string, JsonValue> // 对象
>;
struct JsonValue {
JsonVariant value;
};
总结
- JSON 是互联网上最通用的数据快递包装。
- 语法:大括号包对象,方括号包数组,Key 必须双引号。
- 优点:人眼看得懂,机器好解析,体积小。
为了让你全面理解 JSON,我把例子分成了基础语法、常见结构和真实场景三个类别。
第一类:基础语法演示
这些例子展示了 JSON 支持的最基本数据类型。
1. 最简单的键值对 (Flat Object)
这是最基础的形式,类似于一个简单的字典。
{
"username": "admin",
"timeout": 5000,
"isEnabled": true,
"description": null
}
2. 纯数组 (Array)
JSON 也可以仅仅是一个数组,不包含最外层的键。
[
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
]
3. 各种数字格式
JSON 不区分整数和浮点数,统一为 Number。
{
"integer": 42,
"float": 3.14159,
"negative": -10,
"exponent": 2.5e-3
}
第二类:结构化与嵌套
这是 JSON 最强大的地方,可以无限套娃。
4. 对象中包含数组
比如一个学生选修了多门课。
{
"student_id": 1001,
"name": "李雷",
"courses": [
"高等数学",
"大学英语",
"计算机导论"
]
}
5. 数组中包含对象
这是最常见的数据列表格式(例如商品列表)。
[
{
"id": 1,
"product": "iPhone 15",
"price": 5999
},
{
"id": 2,
"product": "AirPods",
"price": 1299
},
{
"id": 3,
"product": "MacBook",
"price": 9999
}
]
第三类:真实开发场景
这些是你未来写代码时最常遇到的 JSON 格式。
6. 配置文件 (VS Code 风格)
很多软件的 settings.json 就是这样写的。
{
"editor.fontSize": 14,
"editor.fontFamily": "Consolas, 'Courier New', monospace",
"editor.tabSize": 4,
"files.autoSave": "afterDelay",
"workbench.colorTheme": "Default Dark+",
"git.confirmSync": false
}
7. 天气 API 响应数据
当你调用天气接口(如 OpenWeatherMap)时,返回的数据通常包含多层嵌套。
{
"coord": {
"lon": 116.4,
"lat": 39.9
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "晴朗无云",
"icon": "01d"
}
],
"main": {
"temp": 25.5,
"feels_like": 26.1,
"humidity": 40
},
"wind": {
"speed": 3.5,
"deg": 210
},
"city": "Beijing"
}
8. 电商订单信息
一个复杂的订单结构,包含用户信息、地址信息、商品列表(数组)和支付状态。
{
"order_id": "ORD-20231024-001",
"timestamp": "2023-10-24T14:30:00Z",
"user": {
"id": 8848,
"name": "王富贵",
"vip_level": "gold"
},
"shipping_address": {
"province": "广东省",
"city": "深圳市",
"street": "深南大道100号",
"zip": "518000"
},
"items": [
{
"sku": "KB-001",
"name": "机械键盘",
"quantity": 1,
"price": 399.00
},
{
"sku": "MS-002",
"name": "无线鼠标",
"quantity": 2,
"price": 99.50
}
],
"payment": {
"method": "alipay",
"total": 598.00,
"status": "paid"
}
}
9. 游戏存档数据
假设你写一个 RPG 游戏,存档可能长这样。
{
"player": {
"name": "DragonSlayer",
"level": 45,
"hp": 2350,
"max_hp": 2500,
"position": {
"map_id": "dungeon_03",
"x": 120.5,
"y": 45.0,
"z": -10.0
}
},
"inventory": [
{"item_id": "sword_fire", "count": 1, "durability": 85},
{"item_id": "potion_health", "count": 15},
{"item_id": "key_gold", "count": 1}
],
"quests": {
"active": [101, 104],
"completed": [1, 2, 3, 4, 100]
}
}
10. GeoJSON (地理信息)
这是一种专门用来描述地图数据的标准 JSON 格式。
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "某公园"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
}
}
]
}
总结 JSON 的特点:
- 极简:只有
{}、[]、:、,和""这几个符号。 - 严格:
- Example 1 中的 Key (
"username") 必须带双引号。 - Example 5 数组里最后一个元素后面绝对不能加逗号。
- Example 1 中的 Key (
- 万能:无论是简单的配置,还是复杂的3D游戏坐标,都能塞进去。