入门
基本结构
JSON 支持 6 种数据类型:字符串、数字、布尔、null、数组和对象。键必须是双引号字符串。JSON 与语言无关,人和机器都易于读写。
{
"name": "Alice",
"age": 30,
"isStudent": false,
"height": 1.65,
"nullValue": null,
"hobbies": ["reading", "coding", "music"],
"address": {
"city": "NYC",
"zip": "10001"
}
}JSON 语法规则
JSON 语法严格:键和字符串只能用双引号,逗号分隔元素,禁止尾随逗号。整个文档必须是单个 JSON 值。标准 JSON 不支持注释——如需注释,使用预处理器或 JSON5。
{
"key": "value", // key MUST be a double-quoted string
"nested": { "a": 1 }, // objects use { } with comma-separated pairs
"list": [1, 2, 3] // arrays use [ ] with comma-separated values
}
// Rules:
// - Double quotes only for strings and keys (no single quotes)
// - Comma separates members; NO trailing comma
// - The whole document is ONE value (usually an object or array)
// - No comments allowed in standard JSONJSON 中的注释
标准 JSON 禁止注释。常见变通方法:添加 '_comment' 字段(代码忽略)、使用 JSONC/JSON5(VS Code 等工具支持),或用 comment-json、JSON.minify 等库在解析前剥离注释。
// Standard JSON does NOT allow comments.
// Workaround 1: include a descriptive field
{
"_comment": "This is a config file for the app",
"port": 8080
}
// Workaround 2: use JSON5 or JSONC (VS Code settings)
{
// line comment
"port": 8080 /* block comment */
}
// Workaround 3: strip comments before parsing
// (e.g., JSON.minify, comment-json npm package)空白与格式化
字符串外的空白无意义——紧凑形式和美化形式解析结果相同。紧凑 JSON 节省带宽;美化形式(常用 2 空格缩进)提升可读性和 diff 友好度。大多数序列化器提供 'pretty' 选项。
// These are all equivalent:
{"a":1,"b":2} // compact (no whitespace)
{ "a": 1, "b": 2 } // readable
{
"a": 1,
"b": 2
} // pretty-printed
// Whitespace between tokens is insignificant.
// Use compact for transmission, pretty for humans.文件扩展名与 MIME 类型
标准扩展名是 .json,MIME 类型是 application/json。JSONC、JSON5、GeoJSON、NDJSON 等变体有各自约定。始终使用 UTF-8 编码,不推荐使 用 BOM。
// File extensions:
// .json standard JSON
// .jsonc JSON with comments (VS Code, TypeScript config)
// .json5 JSON5 (relaxed syntax)
// .geojson GeoJSON (geographic data)
// .ndjson Newline-Delimited JSON (JSON Lines)
// .har HTTP Archive (JSON-based)
// MIME type:
Content-Type: application/json
// Older/alternate MIME types (avoid):
// text/json (non-standard)
// application/x-json (non-standard)
// UTF-8 is the default and recommended encoding.JSON 值类别
JSON 值分为六种类型:字符串、数字、布尔、null、数组、对象。数组和对象是结构化类型(可容纳其他值),其余是基元类型。合法的 JSON 文档是一个值——通常是对象或数组,但单独的数字或字符串也合法。
// A JSON value is exactly one of these six types:
"hello" // string
42 // number
3.14 // number
true // boolean
false // boolean
null // null
[1, 2, 3] // array
{ "a": 1 } // object
// Structured types: array, object
// Primitive types: string, number, boolean, null
// A standalone JSON document is a single value of any type.数据类型
字符串类型
JSON 字符串是双引号包裹的 Unicode 文本。常见转义:\"(引号)、\\(反斜杠)、\/(斜杠)、\n、\t、\r、\b、\f,以及任意码点的 \uXXXX。不允许用单引号作为字符串分隔符。
{
"single": "double quotes only",
"empty": "",
"escaped": "He said \"hi\" and C:\\Users",
"unicode": "Cafu00e9 \u00e9 \u1F600",
"multiline": "line1\nline2\ttabbed"
}
// Strings MUST use double quotes.
// Single quotes are NOT valid in JSON.数字类型
JSON 数字遵循 IEEE 754 双精度的子集:整数、小数和科学计数法(如 6.022e23)。禁止前导零(007 非法)。NaN、Infinity、-Infinity 不合法——需要时用 null 或字符串表示。
{
"integer": 42,
"negative": -7,
"float": 3.14,
"zero": 0,
"scientific": 6.022e23,
"small": 1.5e-10
}
// Numbers are NOT quoted.
// No leading zeros (007 is invalid).
// No NaN, Infinity, or -Infinity (not valid JSON).布尔类型
JSON 布尔是字面关键字 true 和 false(小写、不加引号)。加引号的 'true'/'false' 是字符串。JSON 语法层没有 0/1 或 yes/no 作为布尔的概念——需要在应用代码中转换。
{
"enabled": true,
"disabled": false,
"flag": true
}
// Booleans are the bare keywords true and false.
// They are NOT quoted ("true" is a string).
// 0/1, yes/no, on/off are NOT booleans in JSON.Null 类型
JSON null 是字面关键字 null(不加引号),表示有意缺失值。它不同于空字符串 ''、0、false、缺失键或空集合。许多语言将 null 映射为 None/nil/null。
{
"middleName": null,
"deletedAt": null,
"optional": null
}
// null is a bare keyword (unquoted).
// "null" (quoted) is a string, not null.
// null represents the intentional absence of value.数组类型
JSON 数组是 [ ] 包裹的有序列表,逗号分隔,从 0 开始索引。可容纳任意 JSON 值,包括混合类型和嵌套数组/对象。空数组 [] 合法。顺序被保留且有意义。
{
"numbers": [1, 2, 3],
"mixed": [1, "two", true, null],
"nested": [[1, 2], [3, 4]],
"objects": [
{ "id": 1 },
{ "id": 2 }
],
"empty": []
}
// Arrays are ordered, zero-indexed, and can hold mixed types.对象类型
JSON 对象是 { } 包裹的无序键值对集合。键必须是唯一的双引号字符串;值可以是任意 JSON 类型。虽然对象概念上无序,但大多数解析器保留插入顺序——不要依赖顺序做正确性保证。
{
"user": {
"id": 1,
"name": "Alice",
"roles": ["admin", "user"],
"active": true
},
"empty": {}
}
// Objects are unordered collections of key/value pairs.
// Keys MUST be unique strings (double-quoted).
// Values can be any JSON type.字符串
字符串基础
JSON 字符串是双引号包裹的 Unicode 字符序列。正斜杠可转义(\/)但非必须——在 <script> 标签中嵌入 JSON 时有用。空字符串合法。
{
"name": "Alice",
"email": "[email protected]",
"url": "https://example.com/path?q=1",
"path": "C:\\Users\\alice",
"empty": ""
}
// Strings are double-quoted Unicode text.
// Forward slash may be escaped as \/ but does not have to be.转义序列
JSON 支持这些转义:\"(引号)、\\(反斜杠)、\/(斜杠)、\b(退格)、\f(换页)、\n(换行)、\r(回车)、\t(制表符)、\uXXXX(Unicode 码点)。其他反斜杠序列均非法。
{
"quote": "She said \"hello\"",
"backslash": "C:\\Users\\name",
"newline": "line1\nline2",
"tab": "col1\tcol2",
"carriage": "a\rb",
"backspace": "a\bb",
"formfeed": "a\fb",
"slash": "a\/b"
}
// Valid escapes: \" \\ \/ \b \f \n \r \t \uXXXXUnicode 字符
用 \uXXXX 表示任意 Unicode 码点。U+FFFF 以上的字符(如许多 emoji)需要代理对:两个 \u 转义。现代解析器也接受原始 UTF-8 字符直接出现在字符串中——\uXXXX 主要用于安全或无法输入字符时。
{
"eacute": "Caf\u00e9",
"euro": "Price: \u20ac10",
"emoji": "Smile \ud83d\ude00",
"chinese": "\u4f60\u597d",
"raw": "Cafu00e9 u00e9 \u00e9"
}
// \uXXXX encodes a code point in the Basic Multilingual Plane.
// Surrogate pairs (two \u escapes) encode characters above U+FFFF.
// Modern parsers also accept the raw UTF-8 character directly.字符串中的特殊字符
JSON 字符串内必须始终转义双引号和反斜杠(\" 和 \\)。其他特殊字符(HTML、SQL、正则)遵循各自规则,但 JSON 只要求转义 \" 和 \\(以及控制字符)。字面反斜杠写作 \\。
{
"html": "<div class=\"x\">Hi</div>",
"sql": "SELECT * FROM t WHERE name='O''Brien'",
"regex": "^\\d{3}-\\d{4}$",
"json": "{ \"k\": \"v\" }",
"cmd": "echo \"hello\""
}
// Backslash is the universal escape character.
// To include a literal backslash, write \\.多行字符串(变通方案)
JSON 字符串不能包含字面换行——必须转义为 \n。多行内容可嵌入 \n、使用行字符串数组,或改用 YAML/JSON5 等支持多行字符串的格式。字面未转义换行是语法错误。
// JSON does NOT support real multi-line strings.
// The following is INVALID:
// { "text": "line1
// line2" }
// Workaround 1: escape the newline
{ "text": "line1\nline2" }
// Workaround 2: array of lines
{ "lines": ["line1", "line2"] }
// Workaround 3: JSON5 allows continued strings (still single logical line)常见字符串陷阱
常见字符串错误:用单引号、留下尾随逗号、忘记转义内部双引号、嵌入字面控制字符(制表/换行)而非 \t/\n 转义。严格解析器会拒绝所有这些。
// WRONG: single quotes
// { 'name': 'Alice' }
// WRONG: trailing comma
// { "a": 1, }
// WRONG: unescaped quote
// { "msg": "He said "hi"" }
// WRONG: literal tab/newline in string
// { "x": "a<TAB>b" }
// RIGHT:
{ "name": "Alice", "msg": "He said \"hi\"" }数字
整数与浮点数
JSON 只有一种数字类型,涵盖整数和浮点数。语法层没有单独的整数类型——语言 绑定可能根据值和库将大整数映射为 int、long、float 或 decimal。
{
"count": 100,
"negative": -42,
"temperature": -273.15,
"pi": 3.14159,
"zero": 0,
"negativeZero": -0
}
// Integers and floats use the same number type.
// JSON does not distinguish int from float at the syntax level.科学计数法
JSON 支持科学计数法:尾数后跟 e 或 E 和可选带符号指数(6.022e23 = 6.022 * 10^23)。e 和 E 均可接受。这对科学数据中的极大或极小数至关重要。
{
"avogadro": 6.022e23,
"planck": 6.626e-34,
"speedOfLight": 2.998e8,
"small": 1.5E-10
}
// e or E is allowed (case-insensitive).
// 6.022e23 means 6.022 * 10^23.
// The exponent may be negative.数字精度
JSON 数字通常被解析为 IEEE 754 双精度,因此 JavaScript 中 2^53-1(9007199254740991)以上的整数会丢失精度。0.1 等小数无法精确表示。对货币或任意精度整数,用字符串编码并在代码中使用 Decimal/BigInteger 类型。
{
"big": 9007199254740993,
"decimal": 0.1,
"sum": 0.1,
"money": 19.99
}
// JavaScript stores numbers as IEEE 754 doubles.
// Integers are safe up to 2^53 - 1 (9007199254740991).
// 0.1 + 0.2 === 0.30000000000000004 (float precision loss).
// For money or big integers, parse as string or use a Decimal type.特殊值(不允许)
标准 JSON 不允许 NaN、Infinity、-Infinity。变通方法:用 null 表示 NaN,将 Infinity 编码为字符串,或用有限哨兵值。某些序列化器(Python json 默认、JSON5)作为扩展输出这些,但产物非标准,严格解析器会拒绝。
// NaN, Infinity, and -Infinity are NOT valid JSON.
// INVALID:
// { "x": NaN }
// { "y": Infinity }
// { "z": -Infinity }
// Common workarounds:
{
"x": null, // represent NaN/null
"y": "Infinity", // encode as a string
"z": 1.7976931348623157e308 // use a finite max
}
// Many serializers (e.g., Python json) accept these as extensions
// but the output is not standard JSON.数字格式
合法 JSON 数字:可选负号、整数部分(除 0 外无前导零)、可选小数部分、可选指数。十六进制(0x)、二进制(0b)、八进制、下划线、前导 +、前导零、两侧无数字的点均非法。
// VALID JSON numbers:
42
-7
0
3.14
-0.5
6.022e23
1.5E-10
100.00
// INVALID:
007 // leading zero
.5 // no leading digit
5. // no trailing digit after dot
+5 // leading plus sign
0x1F // hex
0b101 // binary
1_000 // underscores大数与 BigInt
对 2^53-1 以上的值(如 Twitter snowflake ID、64 位整数、大额余额),用字符串编码以避免精度丢失。若必须在 JSON.parse 中用 reviver 转换数字为 BigInt,注意 BigInt 无法被 JSON.stringify 重新序列化(需 replacer)——传输时用字符串更安全。
{
"snowflake": "1234567890123456789",
"timestamp": 1696000000000,
"balance": "99999999999999999999"
}
// Numbers above 2^53-1 lose precision in JS.
// Use STRINGS for IDs, snowflakes, and big integers.
// In JavaScript, parse with a reviver:
// JSON.parse(str, (k, v) =>
// typeof v === "number" && v > Number.MAX_SAFE_INTEGER
// ? BigInt(v) : v); // careful: BigInt can't be in JSON.stringify
// Better: keep them as strings on the wire.布尔与 Null
布尔值
JSON 布尔是字面关键字 true 和 false。加引号的 'true'/'false' 是字符串。JSON 语法层没有 truthy/falsy 概念——1、0、yes、no、on、off 都是字符串或数字,不是布尔。在应用代码中转换。
{
"enabled": true,
"disabled": false,
"isPublic": true,
"isActive": false
}
// Only two boolean values: true and false (lowercase, unquoted).
// "true" (quoted) is a STRING, not a boolean.
// 1/0, yes/no, on/off are NOT booleans.Null 的含义
JSON null 表示有意缺失值。它不同于缺失键(键不存在)、空字符串 ''、0、false 或空集合。字段存在但无值时用 null;字段本身不适用时省略键。
{
"middleName": null,
"deletedAt": null,
"parent": null,
"optional": null
}
// null means "no value" or "intentionally absent".
// Distinct from:
// - missing key (key not present at all)
// - empty string ""
// - 0 or false
// - empty array [] or object {}Null、空与缺失的区别
三种不同状态:键带空值("")、键显式为 null、缺失键。JavaScript 中 undefined 表示键缺失,而 null 表示存在但无值。API 应文档说明可选字段使用哪种约定。
{
"name": "Alice",
"nickname": "", // empty string (present, empty)
"middleName": null, // explicit null (present, no value)
// "maidenName" // missing (key not in object)
}
// In JavaScript:
// obj.nickname === "" // true
// obj.middleName === null // true
// obj.maidenName === undefined // true (key absent)
// "maidenName" in obj // false
// Choose deliberately: null vs "" vs missing.在条件中使用布尔值
使用 JSON 布尔时,若需区分 false 和缺失,优先用严格比较(=== true)而非 truthy 检查。API 响应中即使为 false 也应包含布尔字段——省略会迫使客户端猜测默认值。
{
"isAdmin": true,
"canEdit": false,
"active": true
}
// In application code (JavaScript):
// if (user.isAdmin) { ... } // truthy check
// const canEdit = user.canEdit === true; // strict boolean check
// Be careful: a missing 'canEdit' key is undefined (falsy),
// but explicit false is also falsy. Distinguish if needed.
// API design: always send the boolean, even when false.常见陷阱
常见陷阱:加引号的 true/false/null 变成字符串;用 True/TRUE/None(Python 风格)或大小写错误为非法;JSON 没有 undefined(只有 null)。唯一合法形式是小写不加引号的关键字 true、false、null。
// Pitfall 1: quoting booleans/null
// { "x": "true" } -> x is a STRING, not a boolean
// { "y": "null" } -> y is a STRING, not null
// Pitfall 2: wrong case
// { "x": True } -> INVALID (Python-style, not JSON)
// { "x": TRUE } -> INVALID
// { "x": None } -> INVALID
// Pitfall 3: confusing null with undefined
// null exists in JSON; undefined does NOT.
// Correct:
{ "x": true, "y": null }数组
数组基础
JSON 数组是 [ ] 包裹的有序、从 0 开始索引的列表,逗号分隔值。空数组和单元素数组合法。顺序有意义且被解析器保留。不允许尾随逗号。
{
"numbers": [1, 2, 3, 4, 5],
"strings": ["a", "b", "c"],
"booleans": [true, false, true],
"empty": [],
"single": [42]
}
// Arrays are ordered, zero-indexed lists in [ ].
// Elements are separated by commas (no trailing comma).
// Empty arrays [] and single-element arrays are valid.混合类型数组
JSON 数组可合法容纳混合类型([1, 'two', true, null])。这合法但通常表明 schema 设计薄弱。同质数组(全字符串或全对象)更易验证、文档化和消费。用 schema 强制元素类型。
{
"mixed": [1, "two", true, null, 3.14],
"nested": [[1, 2], "x", { "a": 1 }]
}
// JSON arrays CAN hold values of different types.
// This is valid but often a sign of weak schema design.
// Prefer homogeneous arrays for clarity and validation.嵌套数组
数组可任意深度嵌套,适用于矩阵、网格和树结构。JSON 不强制嵌套数组等长('ragged' 数组合法)。若需矩形矩阵,用 schema 或应用代码强制。
{
"matrix": [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
],
"ragged": [[1, 2], [3, 4, 5], [6]]
}
// Arrays can nest arbitrarily deep.
// JSON does not enforce rectangular shape—use a schema if needed.对象数组
对象数组是记录列表(用户、产品、帖子)最常见的模式。每个元素通常形状相同,但 JSON 不强制——用 schema(JSON Schema 'items')验证所有元素一致。
{
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" },
{ "id": 3, "name": "Carol" }
],
"empty": []
}
// A very common pattern: a list of records.
// Each element is an object with the same shape.空数组和单元素数组
空数组 [] 和单元素数组合法。API 设计中应区分 [](存在、空列表)、null(存在、无列表)和缺失键(字段不适用)。'无项目' 时返回 [] 通常比 null 更友好。
{
"empty": [],
"single": [42],
"tags": [],
"items": ["one"]
}
// Both forms are valid.
// Distinguish [] from null and from a missing key:
// "tags": [] -> present, empty list
// "tags": null -> present, no list
// // (no tags) -> missing key代码中访问数组
解析后 JSON 数组变为语言的原生数组/列表(JS Array、Python list、Java List 等)。使用标准索引访问、长度和迭代。边界和类型安全由你负责——JSON 本身不强制元素类型。
{
"list": ["a", "b", "c"]
}
// JavaScript:
// const arr = JSON.parse(json).list;
// arr[0] // "a"
// arr.length // 3
// arr.includes("b") // true
// arr.map(x => x.toUpperCase()) // ["A", "B", "C"]
// Python:
// data = json.loads(json_str)
// data["list"][0] # "a"
// len(data["list"]) # 3对象
对象基础
JSON 对象是 { } 包裹的无序键值对集合。键必须是双引号字符串;值可以是任意 JSON 类型。逗号分隔键值对,无尾随逗号。对象是最常见的顶层 JSON 结构。
{
"id": 1,
"name": "Alice",
"email": "[email protected]",
"active": true
}
// Objects are unordered { } collections of key/value pairs.
// Keys MUST be double-quoted strings.
// Pairs are comma-separated (no trailing comma).键命名规则
JSON 键可以是任意双引号字符串,包括空、含空格、点或数字。但为 API 清晰起见,统一使用 camelCase、snake_case 或 kebab-case。公开 API 中避免空格、点(与路径语法冲突)和空键。
{
"simple": "ok",
"with-dash": "ok",
"with_underscore": "ok",
"with.dot": "ok",
"with space": "ok (but avoid)",
"123numeric": "ok (but avoid)",
"": "empty key is valid"
}
// Keys are arbitrary strings (double-quoted).
// Convention: use camelCase, snake_case, or kebab-case consistently.
// Avoid empty keys and keys with spaces/dots in APIs.嵌套对象
对象可任 意深度嵌套,适用于层次数据。深嵌套合法但会损害可读性并增加耦合。公开 API 优先用更扁平的结构或引用(ID)而非深嵌套树。
{
"user": {
"name": "Alice",
"address": {
"street": "123 Main St",
"city": "NYC",
"geo": { "lat": 40.7, "lng": -74.0 }
}
}
}
// Objects can nest arbitrarily deep.
// Deep nesting is valid but can hurt readability—flatten when sensible.带数组的对象
结合对象(键控字段)和数组(有序列表)可建模几乎所有真实数据。常见模式是对象包裹嵌套对象数组(带订单的用户)。用 schema 文档化和验证预期形状。
{
"user": {
"name": "Alice",
"roles": ["admin", "user"],
"orders": [
{ "id": 1, "total": 19.99 },
{ "id": 2, "total": 5.99 }
]
}
}
// Combining objects and arrays models most real-world data.成员顺序
JSON 规范将对象视为无序。实践中大多数现代解析器(JavaScript V8、Python 3.7+、Java LinkedHashMap)保留插入顺序,但不应依赖此做正确性保证。若顺序对哈希或签名重要,显式排序键。
{
"z": 1,
"a": 2,
"m": 3
}
// JSON objects are SPECIFIED as unordered.
// In practice, most parsers (JS, Python 3.7+) preserve insertion order.
// DO NOT rely on order for correctness—sort keys if order matters.
// Sorting keys (e.g., for stable hashing):
// JSON.stringify(obj, Object.keys(obj).sort())重复键
JSON 规范未禁止重复键,但其行为未定义——大多数解析器保留最后一个值,部分保留第一个。重复键是微妙 bug 的常见来源。JSON Schema 可强制 uniqueKeys;linter 和严格解析器可拒绝它们。
// Technically valid JSON, but behavior is UNDEFINED:
{
"name": "Alice",
"name": "Bob"
}
// Most parsers keep the LAST value ("Bob"),
// but some keep the first. Avoid duplicate keys!
// JSON Schema (draft 2019-09+) has 'uniqueKeys' to forbid them.
// JSON.parse in JS keeps the last value (object property override).嵌套结构
深度嵌套
JSON 允许任意嵌套深度,但极深结构损害可读性并可能触及解析器限制(许多解析器施加深度上限,如 1000,以防拒绝服务)。对深层层次数据,优先用更扁平的结构加 ID/引用。
{
"a": {
"b": {
"c": {
"d": {
"e": { "value": 42 }
}
}
}
}
}
// Nesting depth is theoretically unlimited.
// Many parsers impose a limit (e.g., 1000) to prevent DoS.
// Deep nesting hurts readability—consider flattening or references.真实示例
真实 JSON 混合对象和数组来建模实体及其关系。此订单示例嵌套 customer、items(对象数组)和 shipping。用 schema 文档化形状;保持适中嵌套以利可读性。
{
"order": {
"id": "ord-123",
"customer": {
"id": "cus-1",
"name": "Alice",
"email": "[email protected]"
},
"items": [
{ "sku": "A1", "qty": 2, "price": 9.99 },
{ "sku": "B2", "qty": 1, "price": 19.99 }
],
"shipping": {
"address": { "city": "NYC", "zip": "10001" },
"method": "express"
},
"total": 39.97
}
}树结构
树递归建模:每个节点有值和子节点数组。此模式见于文件系统、组织架构图和 AST。注意循环——JSON 无引用语法,故循环图必须用 ID 或序列化为带父指针的扁平列表。
{
"name": "root",
"children": [
{
"name": "child-a",
"children": [
{ "name": "grandchild-1", "children": [] },
{ "name": "grandchild-2", "children": [] }
]
},
{ "name": "child-b", "children": [] }
]
}
// Recursive structures: a node contains an array of child nodes.访问嵌套值
访问深度嵌套值在中间键缺失时有 TypeError/KeyError 风险。用可选链(JS ?. 和 ??)或链式 .get()(Python)加默认值。lodash.get 或 jq 等库简化深度提取并提供默认值。
{
"user": { "address": { "city": "NYC" } }
}
// JavaScript (optional chaining):
// const city = data?.user?.address?.city ?? "unknown";
// Python:
// city = data.get("user", {}).get("address", {}).get("city", "unknown")
// Deep access without guards throws on missing keys.
// Use optional chaining or a helper like lodash.get.扁平化嵌套数据
扁平化嵌套对象(如用 'user.name' 代替 { user: { name } })简化环境变量、表单字段和搜索索引的访问。权衡是丢失结构和更难往返。用库(flat、lodash)扁平化/还原。
// Nested form:
{ "user": { "name": "Alice", "city": "NYC" } }
// Flattened form (dot notation):
{ "user.name": "Alice", "user.city": "NYC" }
// Flattened form (separate keys):
{ "userName": "Alice", "userCity": "NYC" }
// Use cases: environment variables, form fields, search indexing.
// Trade-off: simpler access vs. loss of structure.JSON Schema
Schema 基础
JSON Schema 是描述和验证 JSON 文档的 JSON 词汇。根声明 $schema(草案版本)和 type。properties 列出字段及其类型;required 列出必填键。Ajv(JS)或 jsonschema(Python)等验证器检查一致性。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/user.json",
"title": "User",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 }
},
"required": ["name"]
}类型验证
'type' 关键字验证值的 JSON 类型:string、number、integer、boolean、null、array、object。可以是单个类型或数组(如 ['string', 'null'] 表示可空可选字符串)。'integer' 匹配无小数部分的数字。
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"active": { "type": "boolean" },
"score": { "type": "number" },
"tags": { "type": "array", "items": { "type": "string" } },
"meta": { "type": "object" },
"middle": { "type": ["string", "null"] }
}
}
// 'type' can be a single type or an array of allowed types.字符串约束
字符串约束:minLength、maxLength、pattern(正则)、enum(允许值)和 format(语义提示如 'email'、'uri'、'date-time'、'ipv4')。'format' 默认仅注解——验证器需显式开启才会强制。用 pattern 做严格正则验证。
{
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"maxLength": 254
},
"username": {
"type": "string",
"pattern": "^[a-zA-Z0-9_]{3,20}$",
"minLength": 3,
"maxLength": 20
},
"bio": { "type": "string", "maxLength": 500 }
}
}
// 'format' is a semantic hint (email, uri, date, ipv4).
// 'pattern' is a regular expression.数字约束
数字约束:minimum、maximum(含)、exclusiveMinimum、exclusiveMaximum、multipleOf。对 'integer' 类型,值必须无小数部分。组合约束建模范围(如 1 到 5 的评分)。
{
"type": "object",
"properties": {
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"price": { "type": "number", "minimum": 0, "exclusiveMinimum": 0 },
"rating":{ "type": "integer", "minimum": 1, "maximum": 5 },
"count": { "type": "integer", "multipleOf": 5 }
}
}
// minimum/maximum are inclusive;
// exclusiveMinimum/exclusiveMaximum are exclusive.对象与数组约束
数组约束:items(元素 schema)、minItems、maxItems、uniqueItems。对象约束:required(必填键)、properties(字段 schema)、additionalProperties(false 禁止额外键,或为其指定 schema)、minProperties、maxProperties。
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"tags": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
},
"required": ["id"],
"additionalProperties": false
}
// minItems/maxItems/uniqueItems constrain arrays.
// required lists mandatory keys; additionalProperties
// controls whether extra keys are allowed.高级验证
高级 JSON Schema:oneOf/anyOf/allOf 组合子 schema;$ref 引用可复用定义;if/then/else 应用条件验证;const 要求精确值;enum 列出允许值。这些让你表达丰富约束和可复用类型。
{
"oneOf": [
{ "type": "string" },
{ "type": "integer" }
],
"definitions": {
"address": {
"type": "object",
"properties": { "city": { "type": "string" } }
}
},
"properties": {
"home": { "$ref": "#/definitions/address" },
"work": { "$ref": "#/definitions/address" }
},
"if": { "properties": { "type": { "const": "vip" } } },
"then": { "required": ["discount"] }
}
// oneOf/anyOf/allOf combine schemas.
// $ref reuses definitions; if/then/else is conditional.JSONPath
JSONPath 语法
JSONPath 是 JSON 查询语言,灵感来自 XPath。'$' 是根,'.' 选子节点,'[index]' 选数组元素,'*' 是通配符,'..' 是递归下降。jsonpath-plus(JS)或 jsonpath-ng(Python)等库实现它。
// JSONPath queries JSON like XPath queries XML.
// Sample data:
{
"store": {
"book": [
{ "category": "fiction", "price": 12.99 },
{ "category": "web", "price": 29.99 }
]
}
}
// Common JSONPath expressions:
$.store.book[0].category // "fiction"
$.store.book[*].price // [12.99, 29.99]
$..price // all prices anywhere
$.store..category // all categories under store根与子节点
'$' 引用根。'.' 按名选子节点;'[]' 是括号替代形式,可处理含点、空格或引号的键。'[index]' 选数组元素(0 开始);部分实现支持负索引从末尾计数。
// '$' = root object/array
// '.' or '[]' = child
$.user.name // dot notation
$['user']['name'] // bracket notation (use for special chars)
$.users[0] // first element of users array
$.users[-1] // last element (some implementations)
// Use bracket notation when keys contain dots, spaces, or quotes:
$['user.name']
$['first name']递归下降
'..'(递归下降)匹配任意深度的键或元素。'$..price' 返回无论何处出现的每个 'price' 值。'$..*' 返回每个节点。当不知道确切路径时,这对搜索大型或深嵌套 JSON 非常有用。
{
"a": { "b": { "c": 1 }, "c": 2 }
}
// '..' searches at all depths:
$..c // [1, 2] (all 'c' keys anywhere)
$..a // all 'a' keys
$..* // every node (everything)
// Useful for finding a key without knowing the exact path:
$..price // every price, no matter how nested过滤表达式
过滤器用 [?(表达式)],'@' 指当前项。支持的运算符因实现而异,但通常包括 ==、!=、<、<=、>、>=、&&(与)、||(或),有时还有 =~ 正则。length()、contains() 等函数增加能力。
// Filter with [?(expression)]:
$.store.book[?(@.price < 20)] // books under 20
$.store.book[?(@.category == 'web')] // web books
$.store.book[?(@.price < 30 && @.category == 'web')]
// '@' refers to the current item being filtered.
// Operators: == != < <= > >= && || =~ (regex in some impls)
// Functions: length(), contains(), matches()通配符
'*' 是通配符,匹配对象所有子节点或数组所有元素。'$.users[*].name' 返回每个用户的 'name'。'$..*' 返回每个节点。结果以匹配数组返回,即使只有一个。
{
"users": [
{ "name": "Alice", "age": 30 },
{ "name": "Bob", "age": 25 }
]
}
// '*' matches all elements/children:
$.users[*] // all user objects
$.users[*].name // ["Alice", "Bob"]
$.users[0].* // all values of first user: ["Alice", 30]
$..* // every node in the document
// Wildcards return arrays of matches.常见函数与示例
JSONPath 函数因实现而异:length()、min()、max()、avg()、sum()、contains()、matches() 常见。组合过滤器和递归下降可做强大查询。命令行工作首选 jq,它使用略不同的语法。
// length(): array length or string length
$.users.length() // number of users
$.store.book[?(@.title.length() > 10)]
// min(), max(), avg(), sum() (some implementations)
$.store.book..price.min()
// Realistic query: titles of cheap web books
$.store.book[?(@.price < 20 && @.category == 'web')].title
// Tools: jq (CLI), jsonpath-plus (JS), jsonpath-ng (Python),
// Jayway (Java), GoJSONQ (Go)JSON 与 XML 及 YAML
JSON 与 XML 语法
JSON 更轻量(无闭合标签,数字/布尔/null 原生类型)且直接映射大多数语言数据结构。XML 更重但更丰富:属性、命名空间、混合内容、schema(XSD)和转换(XSLT) 。JSON 主导 Web API;XML 持续用于企业/SOAP。
// JSON:
{
"name": "Alice",
"age": 30,
"hobbies": ["reading", "coding"]
}
<!-- XML: -->
<person>
<name>Alice</name>
<age>30</age>
<hobbies>
<hobby>reading</hobby>
<hobby>coding</hobby>
</hobbies>
</person>
// JSON: lighter, no closing tags, types (number/boolean/null).
// XML: heavier, supports attributes, namespaces, mixed content.JSON 与 YAML 语法
YAML 用缩进代替大括号/引号,支持注释、多行字符串和锚点/别名。JSON 更严格(需引号、无注释)但更快更普及。YAML 是 JSON 超集——每个合法 JSON 文件也是合法 YAML。
# YAML:
name: Alice
age: 30
hobbies:
- reading
- coding
// JSON (equivalent):
{
"name": "Alice",
"age": 30,
"hobbies": ["reading", "coding"]
}
// YAML: no quotes/braces, indentation-based, supports comments.
// JSON: stricter, faster to parse, ubiquitous in APIs.JSON 转 YAML
因 YAML 是 JSON 超集,JSON 转 YAML 很直接。Python 的 yaml.dump 和 Node 的 js-yaml 处理。结果用缩进且(大多)无引号。YAML 的注释和多行字符串无法从 JSON 往返(JSON 没有这些)。
// JSON input:
{ "name": "Alice", "roles": ["admin", "user"] }
// YAML output:
name: Alice
roles:
- admin
- user
// Python:
// import yaml, json
// yaml.dump(json.loads(json_str), sort_keys=False)
// Node.js:
// const yaml = require('js-yaml');
// yaml.dump(JSON.parse(jsonStr));YAML 转 JSON
简单 YAML 转 JSON 可行,但会丢失 YAML 特有特性:注释、锚点/别名、多文档流、标签和复杂键。用 yaml.safe_load 避免自定义标签的任意代码执行。结果为标准 JSON。
# YAML input:
server:
host: localhost
port: 8080
debug: true
// JSON output:
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true
}
}
// Python:
// import yaml, json
// json.dumps(yaml.safe_load(yaml_str), indent=2)
// Watch for YAML-specific features: anchors, tags, multi-docs.数据建模差异
JSON 用对象和数组建模数据——无属性或命名空间。XML 增加属性、命名空间、混合内容和丰富 schema。YAML 增加注释、锚点和多文档支持。TOML 面向配置文件的表。按需选择:API(JSON)、文档(XML)、配置(YAML/TOML)。
// JSON: objects and arrays, no attributes.
// Attribute-style metadata needs a convention (e.g., @_prefix).
// XML: elements + attributes, namespaces, mixed content.
// <book id="b1" category="web"><title>...</title></book>
// YAML: maps, sequences, scalars, anchors, multi-doc.
// Supports comments and multi-line strings natively.
// TOML: tables + key/value, designed for config files.
// Best for configuration; not ideal for nested data.何时使用各格式
JSON 用于 Web API 和 NoSQL 存储(通 用、快速)。XML 用于企业服务、文档中心数据(SVG、XHTML)和丰富 schema。YAML 用于人写的配置(CI/CD、docker-compose),得益于注释和可读性。TOML 用于小型配置文件。按用例匹配格式。
// Use JSON when:
// - building web/REST APIs (universal browser support)
// - storing structured data (NoSQL databases)
// - configuration with simple needs (package.json)
// Use XML when:
// - enterprise/SOAP web services
// - documents with mixed content (SVG, XHTML, DocBook)
// - you need schemas, namespaces, or XSLT transforms
// Use YAML when:
// - human-written config (CI/CD, docker-compose)
// - you need comments and multi-line strings
// Use TOML when:
// - small config files (Cargo, pyproject)JavaScript 中的解析
JSON.parse
JSON.parse 将 JSON 字符串转为 JavaScript 值。接受任何合法 JSON 值(对象、数组、字符串、数字、布尔、null)。非法 JSON 抛出 SyntaxError。处理不可信输入时始终用 try/catch 包裹 JSON.parse。