新手指南:什麼是 JSON?JSON.stringify 與 JSON.parse 完整教學

更新日期: 2025 年 5 月 26 日

本文為 AJAX 基本介紹系列文,第 12 篇:

  1. 初學者指南:什麼是HTTP 方法?
  2. 網頁狀態碼(HTTP Status Code)指南:從分類到常見應用
  3. 新手指南:什麼是同步與非同步?
  4. 新手指南:什麼是 AJAX?
  5. 新手指南:什麼是 XMLHttpRequest?
  6. 初學者指南:了解 JavaScript 的 fetch 函數
  7. 深入理解Fetch 函數的第二個參數
  8. 初學者指南:了解JavaScript 的Promise 物件
  9. JavaScript 中的await 關鍵字:從fetch 到現代非同步處理
  10. 初學者指南:了解JavaScript 中的Promise 和await
  11. fetch 方法到底取得的東西是什麼?
  12. 新手指南:什麼是 JSON? 👈進度

在前端或後端開發中,開發者經常會需要將 JavaScript 物件轉換成字串格式來儲存、傳輸,或是接收一段字串並還原成 JavaScript 能操作的資料。

這時候,JavaScript 提供了兩個重要的方法:

  • JSON.stringify():將 JavaScript 資料轉換成 JSON 字串
  • JSON.parse():將 JSON 字串還原成 JavaScript 資料

這篇文章將詳細介紹這兩個方法的用途、語法、實例與常見陷阱,幫助你在實務中正確操作資料格式。

什麼是 JSON?

在現代的 Web 應用中,資料總是需要「流動」的——從前端傳到後端、從伺服器傳回瀏覽器、從一台裝置同步到另一台。

為了讓這些資料在不同系統間順利交換,我們需要一種通用且結構清晰的格式來表示它。

這就是 JSON(JavaScript Object Notation) 的角色。

雖然名稱裡有 JavaScript,但 JSON 早已不只是 JavaScript 專屬,而是一種跨平台的資料表示格式。

幾乎所有程式語言都能讀懂 JSON,包括 Python、Java、Go、PHP 等,因此它成為 Web 開發中的通用語言,用來描述與傳遞結構化資料。

JSON 是一種「格式」,不是一種型別

初學者常常會問:「JSON 是不是一種資料型別?」這是一個關鍵的觀念。

事實上,JSON 是一種資料格式(data format)

它的本質是一段字串,只是這段字串遵循特定的語法結構,使它看起來很像 JavaScript 的物件或陣列。

這也是為什麼 JSON 能夠被輕易地還原成 JavaScript 的資料型別。

例如,以下這段 JSON:

{
  "name": "小明",
  "age": 18,
  "isStudent": true
}

看起來就像是一個 JavaScript 物件,但實際上如果你用 JavaScript 儲存這段 JSON,它是一個字串,需要用 JSON.parse() 才能轉回可以操作的物件。

相對地,如果你有一個 JavaScript 物件要傳送給伺服器,就需要先用 JSON.stringify() 將它轉成 JSON 字串,才能符合 HTTP 的傳輸規格。

JSON 不只能表示物件,也可以是陣列

許多人學習 JSON 時,第一個接觸的例子通常是「物件格式」,例如描述一位使用者、一本書、一筆訂單等。

然而,JSON 同樣可以用「陣列」作為最外層的結構,這點非常重要,尤其是在處理多筆資料時。

來看看一個典型的例子:

[
  { "id": 1, "name": "小明" },
  { "id": 2, "name": "小華" },
  { "id": 3, "name": "小美" }
]

這是一個 JSON 陣列,其中的每一項都是一個物件,代表不同的使用者。

這種格式非常適合用來表示「清單」資料,例如留言列表、商品集合、通知記錄等。

🧠 為什麼 JSON 可以用陣列表示?

根據 JSON 的語法標準(RFC 8259),JSON 的資料結構可以從以下兩種形式開始:

  1. 物件(Object):以 {} 包裹,包含一組「鍵值對」
  2. 陣列(Array):以 [] 包裹,包含一組有順序的資料項目

不論你用哪一種起手式,裡面的資料仍然可以是巢狀的——例如陣列中可以放物件,物件的屬性值也可以是陣列。

這樣的設計,讓 JSON 成為一種極度彈性且結構化的資料格式。

陣列與物件:該用哪一種?

在實務上,我們會根據資料內容的型態來選擇 JSON 的結構:

使用情境建議格式範例
傳送單一筆資料物件{ "id": 1, "title": "文章標題" }
傳送多筆資料(清單)陣列[ { "id": 1 }, { "id": 2 } ]
結合兩者(清單中有物件)陣列包物件[ { "user": { "name": "小明" } } ]

前端從伺服器取得 API 回應時,若資料是一筆,通常是物件格式;若是多筆,則多為陣列格式。

你也可以在陣列中放入巢狀的物件或其他陣列,根據需求彈性設計。

JSON.parse():將字串還原為 JavaScript 資料

在 Web 開發中,資料往往是以字串的形式從伺服器回傳的。

這時我們無法直接操作這些資料,因為它們只是看起來像物件的字串而已。

要讓這些字串變成 JavaScript 能操作的資料結構,我們就需要使用 JSON.parse()

功能說明

JSON.parse() 是 JavaScript 提供的標準方法,用來將一段符合 JSON 語法的字串,還原成 JavaScript 原生資料型別

這包括物件(Object)、陣列(Array)、數字、布林值等。

這個方法的本質就像是「資料解碼器」,負責把從伺服器、檔案或瀏覽器儲存空間中讀取到的 JSON 字串,轉換為可以操作的 JavaScript 變數。

使用範例:解析一段字串成物件

const str = '{"name":"小明","age":18}';
const obj = JSON.parse(str);

console.log(obj.name); // 👉 "小明"
console.log(obj.age);  // 👉 18

這裡我們看到,原本的 str 是一段字串(用雙引號包住的 JSON 格式內容),透過 JSON.parse() 還原後,變成了一個真正的 JavaScript 物件,裡面的屬性就可以用點語法(dot notation)來存取。

常見用途

使用情境說明
API 回應解析從伺服器取得的資料常以 JSON 字串傳回,需先解析才能使用。
localStorage 取出資料儲存在 localStorage 的資料只能是字串,取出後需還原為物件。
檔案讀取使用者上傳 JSON 檔案時,可用 JSON.parse() 解析內容。

📌 範例:從 localStorage 取得使用者資料

const savedUser = localStorage.getItem("user"); // 👉 '{"name":"小明","age":18}'
const user = JSON.parse(savedUser);             // 👉 { name: "小明", age: 18 }

console.log(user.name); // 👉 小明

注意事項與錯誤處理

JSON.parse() 只接受符合 JSON 語法的字串,如果格式錯誤,會直接拋出錯誤(throw error),造成程式中斷。

❌ 錯誤範例:

JSON.parse("{name: '小明'}"); // 錯誤:key 未加引號,值用單引號

✅ 正確格式應為:

JSON.parse('{"name": "小明"}'); // JSON 格式必須使用雙引號

✅ 建議加上錯誤處理:

try {
  const data = JSON.parse(inputStr);
  console.log(data);
} catch (error) {
  console.error("JSON 格式錯誤:", error.message);
}

使用 try...catch 能夠避免不合法 JSON 造成應用程式崩潰,尤其是在處理用戶輸入或外部 API 回傳時特別重要。

JSON.stringify():將資料轉為 JSON 字串

如果說 JSON.parse() 是「解碼器」,那麼 JSON.stringify() 就是「編碼器」。

它的功能就是將 JavaScript 中的資料(物件、陣列、數字、布林值)轉換成符合 JSON 語法的字串,方便儲存或傳輸。

功能說明

JSON.stringify() 會將 JavaScript 的變數轉換為一段 JSON 格式的字串,這段字串通常會被用來:

  • 儲存在 localStorage
  • 傳送到伺服器作為 POST/PUT 請求的 body
  • 輸出到檔案系統(例如匯出設定、儲存快取)

使用範例:物件轉為字串

const obj = { name: "小明", age: 18 };
const jsonStr = JSON.stringify(obj);

console.log(jsonStr); // 👉 '{"name":"小明","age":18}'

這裡的 jsonStr 是一個 JavaScript 字串(typeof jsonStr === "string"),它符合 JSON 格式,可以安全地儲存或傳輸。

常見用途

使用情境說明
儲存到 localStoragelocalStorage 僅支援字串類型,需先轉換。
傳送 HTTP 資料fetch、axios 等 API 的請求 body 通常需為 JSON 字串。
儲存 JSON 檔案將資料寫入檔案時可使用 JSON 格式。

📌 範例:將使用者資料存入 localStorage

const user = { name: "小明", age: 18 };
localStorage.setItem("user", JSON.stringify(user));

🧩 進階用法:美化輸出(縮排)

在開發或除錯時,有時希望讓輸出的 JSON 更容易閱讀。這時可以使用 stringify() 的第三個參數來加上縮排格式:

const formatted = JSON.stringify(obj, null, 2);
console.log(formatted);

輸出結果:

{
  "name": "小明",
  "age": 18
}

這種格式在除錯輸出、檔案儲存、或 API 文件展示時非常有幫助。

JSON 在 HTTP 中的角色:前後端溝通的資料語言

在現代的 Web 應用中,前端與後端幾乎無時無刻不在溝通,而這種溝通的媒介,最常見的就是 HTTP(超文字傳輸協定)。

當一個使用者點擊按鈕、送出表單、或瀏覽某個頁面時,前端通常會發送一個 HTTP 請求給後端伺服器,請求某些資料或提交某些資訊。

而在這個資料交換的過程中,JSON 幾乎已經成為標準格式

將資料從前端送到後端:使用 JSON 傳遞請求資料

當前端需要將使用者填寫的表單資料(如姓名、年齡、信箱)送到後端時,這些資料一開始是存在 JavaScript 的物件中。

為了讓後端能夠正確解析這些資料,我們會先用 JSON.stringify() 把 JavaScript 物件轉成 JSON 格式的字串,並透過 HTTP 請求的 body 傳送出去。

同時,我們也必須設定一個關鍵的 HTTP 標頭(header):Content-Type: application/json,這樣伺服器才能知道傳入的資料格式是 JSON。

✅ 實際範例:

fetch("/api/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json" // 告知後端資料格式為 JSON
  },
  body: JSON.stringify({
    name: "小明",
    age: 18
  }) // 把物件轉成字串後傳送
});

這裡的請求會把以下 JSON 字串送到後端:

{"name":"小明","age":18}

後端伺服器收到這段字串後,會使用對應語言的 JSON 解析器(如 Node.js 的 JSON.parse()、Python 的 json.loads())來還原為可操作的資料物件,進一步儲存或處理。

從後端取得資料:解析 JSON 回應

資料交換不僅僅是單向傳送,後端通常也會將處理結果回傳給前端,例如:

  • 使用者登入後的資料
  • 查詢的結果列表
  • 表單提交後的狀態回饋

這些回應幾乎也都是以 JSON 格式回傳。前端收到這些 JSON 字串後,需再將它們還原為 JavaScript 可用的物件或陣列。

這時就會使用 Response.prototype.json() 方法來自動解析。

✅ 取得後端資料的範例:

fetch("/api/users")
  .then(response => response.json()) // 相當於 JSON.parse()
  .then(data => {
    console.log(data); // 取得還原後的 JavaScript 資料
  });

這段程式碼會自動將伺服器傳回的 JSON 字串轉為 JavaScript 物件,讓你可以直接使用 data.namedata.id 等屬性。

前後端溝通的流程總覽

以下是以 JSON 為基礎的資料交換流程圖解:

  1. 前端資料準備:將 JavaScript 物件用 JSON.stringify() 編碼為 JSON 字串
  2. 發送 HTTP 請求:設定 Content-Type: application/json,將 JSON 字串作為請求 body 傳送出去
  3. 後端接收並解析:伺服器收到請求後,透過 JSON 解析器還原資料
  4. 伺服器處理邏輯:執行資料驗證、查詢資料庫、進行邏輯運算等
  5. 伺服器回傳 JSON 結果:回應 JSON 字串給前端
  6. 前端解析回應:使用 .json() 將字串轉為 JavaScript 物件,進行畫面更新或其他操作

🌍 為什麼選擇 JSON?

JSON 成為資料交換主流格式的原因很多,以下是幾個最關鍵的特性:

特性說明
可讀性高JSON 結構簡單清晰,開發者易於理解與除錯
體積小相比 XML,JSON 更簡潔,適合網路傳輸
語言支援廣泛幾乎所有主流語言都有內建 JSON 處理函式
結構彈性支援巢狀結構、陣列、物件混用,能完整表示資料層次
相容 JavaScript直接對應 JavaScript 物件,前端使用起來特別自然

常見錯誤與陷阱:避免落入 JSON 使用的雷區

雖然 JSON.stringify()JSON.parse() 用法看似簡單直觀。

但實際使用時,初學者很容易因為不熟悉 JSON 的語法規範或特性,而導致資料錯誤、程式崩潰,甚至出現難以追蹤的 bug。

本章節整理了幾個常見錯誤與陷阱,幫助你在實務開發中避開地雷。

錯誤一:JSON 格式錯誤造成解析失敗

❌ 錯誤寫法:

JSON.parse("{name: '小明'}"); // 會拋出錯誤:Unexpected token n

🔍 錯誤原因解析:

這是 JSON 語法最容易犯的錯誤。

雖然這段內容在 JavaScript 中看起來像是物件,但它不是合法的 JSON 字串,因為:

  1. 屬性名稱(key)必須加上雙引號:不能省略,也不能使用單引號
  2. 字串值也必須使用雙引號:JSON 不接受單引號

✅ 正確寫法:

JSON.parse('{"name": "小明"}');

在 JSON 中,一律使用雙引號包住字串與屬性名稱,這與 JavaScript 物件語法的彈性不同,是 JSON 的硬性規定。

🧠 延伸建議:

  • 在處理外部 JSON 字串時,務必先檢查格式是否合法
  • 可使用 JSONLint 等線上工具驗證格式
  • 如果你是從手寫字串、HTML 表單輸入或第三方 API 取得 JSON,建議搭配 try...catch 捕捉錯誤避免崩潰

錯誤二:JSON.stringify 忽略函式與 undefined

💡 什麼意思?

當你將一個包含函式或 undefined 屬性的物件轉成 JSON 字串時,這些值會自動被忽略,完全不會出現在輸出的字串中

❌ 範例:

const obj = {
  name: "小明",
  sayHi: function () {},
  age: undefined
};

console.log(JSON.stringify(obj)); 
// 👉 輸出結果:'{"name":"小明"}'

你可能會以為整個物件都會被序列化進 JSON,但實際上,sayHiage 被省略了。

🔍 為什麼會這樣?

根據 JSON 標準(ECMA-404),JSON 格式僅支援以下資料型別:

  • 字串(String)
  • 數字(Number)
  • 布林值(Boolean)
  • 陣列(Array)
  • 物件(Object)
  • null

因此,不支援函式(function)、undefined、Symbol、BigInt、DOM 元素等非 JSON 型別

這些型別在序列化時會被自動過濾掉,或觸發錯誤。

🧠 實務提醒:

  • 不要把需要保留的邏輯(如函式)寫在資料物件中,否則會在 stringify 過程中消失
  • 若需要自訂 stringify 行為,可使用 toJSON() 方法或傳入 replacer 函式

錯誤三:循環引用造成序列化錯誤

❌ 範例:

const a = {};
a.self = a;

JSON.stringify(a); // ❌ Uncaught TypeError: Converting circular structure to JSON

🔍 問題解釋:

a 這個物件有一個屬性 self 指向自己,形成「循環引用(circular reference)」,這在 JSON 的序列化過程中無法被正確轉換,會直接拋出錯誤。

✅ 解決方式:

你可以使用第三方函式庫(如 flatted)或自行過濾掉循環結構。

結語:養成格式轉換的好習慣

JSON.stringifyJSON.parse 是每一位 JavaScript 工程師的基本工具。

無論你是要操作 localStorage、串接 API,還是進行資料儲存與傳輸,都會頻繁使用這兩個方法。

熟練這兩者的用法,不僅可以讓你更靈活處理資料,也能避免常見錯誤與 debug 疲勞。

建議你多練習轉換實例,搭配 try...catch 處理例外狀況,打造更穩定的應用程式!

Similar Posts