跳至內容

什麼是 JSON?實用入門指南

JSON 是 Web 上最常見的資料交換格式。本指南說明它的值型別、語法規則,以及最容易踩到的陷阱。

JSON(JavaScript Object Notation)是一種以純文字表示結構化資料的格式。 它是 HTTP API 預設的共通語言,也是現代設定檔、日誌、訊息佇列最普遍的 資料格式。只要你今天還在寫程式,幾乎每天都在讀寫 JSON。

本文介紹 JSON 的由來、六種值型別、必須遵守的語法規則,以及它與外表 相似的 JavaScript 物件字面值有哪些關鍵差異。

JSON 的由來

JSON 由 Douglas Crockford 在 2000 年代初期自 JavaScript 中抽出,作為 極簡的序列化格式。它有兩份語法相同的標準文件:ECMA-404RFC 8259,兩者定義同一套封閉且無歧義的語法。

這種刻意的極簡是 JSON 的設計核心。它沒有 schema、沒有註解、沒有 參照、沒有日期型別,也沒有二進位型別。它擁有的只是一份小到所有 主流語言都能在標準函式庫提供解析器的文法。

六種 JSON 值型別

每份 JSON 文件就是一個 value,而 value 必定是以下六者之一:

  1. string——以雙引號包圍的 Unicode 文字:"hello"
  2. number——十進位數字:42-3.141.2e10。沒有 NaNInfinity
  3. boolean——truefalse
  4. null——字面值 null
  5. object——以字串為鍵的無序集合:{"name": "Ada", "age": 36}
  6. 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.jsontsconfig.jsoncomposer.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。
  • 單引號——字串與鍵都必須使用雙引號。
  • NaNInfinity——不是合法的 JSON 數字。用 null 或字串代替。
  • 大數——JSON 數字是十進位文字,但 JavaScript 解析器會轉成 64-bit 浮點數,超過 2^53 就會失真。對於金額或 ID,請以字串序列化
  • 日期——JSON 沒有日期型別。慣例是 ISO 8601 字串("2026-05-13")。
  • 編碼——JSON 採 Unicode,通常為 UTF-8。檔頭的 BOM 會讓嚴格解析器報錯。

若一份文件看起來沒問題卻無法解析, JSON 驗證工具 通常能指出出錯的位元組位置。

延伸閱讀