什麼是 JSON?實用入門指南
JSON 是 Web 上最常見的資料交換格式。本指南說明它的值型別、語法規則,以及最容易踩到的陷阱。
JSON(JavaScript Object Notation)是一種以純文字表示結構化資料的格式。 它是 HTTP API 預設的共通語言,也是現代設定檔、日誌、訊息佇列最普遍的 資料格式。只要你今天還在寫程式,幾乎每天都在讀寫 JSON。
本文介紹 JSON 的由來、六種值型別、必須遵守的語法規則,以及它與外表 相似的 JavaScript 物件字面值有哪些關鍵差異。
JSON 的由來
JSON 由 Douglas Crockford 在 2000 年代初期自 JavaScript 中抽出,作為 極簡的序列化格式。它有兩份語法相同的標準文件:ECMA-404 與 RFC 8259,兩者定義同一套封閉且無歧義的語法。
這種刻意的極簡是 JSON 的設計核心。它沒有 schema、沒有註解、沒有 參照、沒有日期型別,也沒有二進位型別。它擁有的只是一份小到所有 主流語言都能在標準函式庫提供解析器的文法。
六種 JSON 值型別
每份 JSON 文件就是一個 value,而 value 必定是以下六者之一:
- string——以雙引號包圍的 Unicode 文字:
"hello"。 - number——十進位數字:
42、-3.14、1.2e10。沒有NaN或Infinity。 - boolean——
true或false。 - null——字面值
null。 - object——以字串為鍵的無序集合:
{"name": "Ada", "age": 36}。 - array——有序的值列表:
[1, 2, 3]。
物件與陣列可以任意巢狀,這也是 JSON 能夠表達複雜文件的關鍵。
物件與陣列
兩種容器型別各有用途。物件 將名稱對應到值——當欄位本身有意義時 使用:
{
"id": "user_123",
"email": "ada@example.com",
"active": true
}
陣列 是有序序列——當僅順序重要時使用:
["red", "green", "blue"]
實務上兩者組合運用。列出使用者的 API 回應幾乎都是物件陣列:
[
{ "id": "user_1", "email": "ada@example.com" },
{ "id": "user_2", "email": "alan@example.com" }
]
JSON 物件的鍵 永遠是字串,且規格要求每個鍵在同一物件內唯一。 接受重複鍵的解析器通常會保留最後一個值,但絕不要倚賴這個行為。
JSON 與 JavaScript 物件字面值
JSON 看起來像 JavaScript,但它是嚴格的子集,差異不容忽視。以下是 合法的 JS 物件字面值,但不是合法的 JSON:
{
name: 'Ada', // 鍵未加引號、字串用單引號
tags: ['a', 'b',], // 多餘的逗號
born: new Date(), // 函式呼叫
bio: undefined, // undefined 不是 JSON 值
}
同一份資料寫成合法的 JSON:
{
"name": "Ada",
"tags": ["a", "b"],
"born": "1815-12-10T00:00:00Z",
"bio": null
}
三條規則涵蓋大部分差異:鍵必須是加雙引號的字串、字串使用雙引號、
結尾不能有多餘逗號。JSON 沒有 undefined,用 null 或直接省略
該鍵即可。
若手上有混合 JSON 與 JS 寫法的資料,可以用 JSON 修復工具 一次轉成合法 JSON。
JSON 用在哪裡
- HTTP API——幾乎所有 REST API 都使用 JSON,
Content-Type: application/json。 - 設定檔——
package.json、tsconfig.json、composer.json等等。 - 結構化日誌——每行一筆 JSON(NDJSON)已是日誌收集的標準。
- 文件資料庫——MongoDB、DynamoDB、CouchDB 以 JSON 形狀儲存文件。
- Web 訊息——
postMessage、WebSocket、Server-Sent Events 都載著 JSON。
三種語言的讀寫範例
每種主流語言的標準函式庫都有解析器,API 的形狀相似:將值序列化為字串、 將字串解析為值。
JavaScript:
const obj = JSON.parse('{"a":1,"b":[2,3]}');
const text = JSON.stringify(obj, null, 2);
Python:
import json
obj = json.loads('{"a":1,"b":[2,3]}')
text = json.dumps(obj, indent=2)
Go:
import "encoding/json"
var obj map[string]any
json.Unmarshal([]byte(`{"a":1,"b":[2,3]}`), &obj)
out, _ := json.MarshalIndent(obj, "", " ")
常見陷阱
- 結尾逗號——在 JSON 中不合法,即使大多數 JS 格式化器會自動加上。
- 註解——JSON 沒有
//與/* */。JSON5 與 JSONC 有,但它們不是 JSON。 - 單引號——字串與鍵都必須使用雙引號。
NaN與Infinity——不是合法的 JSON 數字。用null或字串代替。- 大數——JSON 數字是十進位文字,但 JavaScript 解析器會轉成 64-bit 浮點數,超過 2^53 就會失真。對於金額或 ID,請以字串序列化。
- 日期——JSON 沒有日期型別。慣例是 ISO 8601 字串(
"2026-05-13")。 - 編碼——JSON 採 Unicode,通常為 UTF-8。檔頭的 BOM 會讓嚴格解析器報錯。
若一份文件看起來沒問題卻無法解析, JSON 驗證工具 通常能指出出錯的位元組位置。
延伸閱讀
- 與其他格式比較:JSON、YAML 與 XML 比較。
- 解析失敗時的對照表:常見 JSON 語法錯誤。
- 加上結構驗證:JSON Schema 新手入門。
- 隨時格式化或壓縮:/zh-Hant/json/formatter。