JSON 與 JavaScript 文字

JSON 代表 JavaScript Object Notation,但它不是 JavaScript。可以把它看成只是一個資料序列化格式,恰好是可直接用作一個 JavaScript 字面。但是,不建議直接執行(即通過 eval())從外部源獲取的 JSON。從功能上講,JSON 與 XML 或 YAML 沒有什麼不同 - 如果將 JSON 想象成一種看起來非常像 JavaScript 的序列化格式,則可以避免一些混淆。

即使名稱僅僅意味著物件,即使通過某種 API 的大多數用例總是碰巧是物件和陣列,JSON 也不僅僅是物件或陣列。支援以下基元型別:

  • 字串(例如 Hello World!
  • 數字(例如 42
  • 布林值(例如 true
  • 價值 null

在序列化時將從 JSON 中省略未定義屬性的意義上不支援 undefined。因此,無法反序列化 JSON 並最終獲得值為 undefined 的屬性。

字串 42 是有效的 JSON。JSON 並不總是必須有 {...}[...] 的外部信封。

雖然 nome JSON 也是有效的 JavaScript,而一些 JavaScript 也是有效的 JSON,但兩種語言之間存在一些細微差別,而且兩種語言都不是另一種語言的子集。

以下面的 JSON 字串為例:

{"color": "blue"}

這可以直接插入 JavaScript。它在語法上是有效的,並將產生正確的值:

const skin = {"color": "blue"};

但是,我們知道 color 是有效的識別符號名稱,並且可以省略屬性名稱周圍的引號:

const skin = {color: "blue"};

我們也知道我們可以使用單引號而不是雙引號:

const skin = {'color': 'blue'};

但是,如果我們要同時使用這兩個文字並將它們視為 JSON,那麼它們在語法上都不是有效的 JSON:

{color: "blue"}
{'color': 'blue'}

JSON 嚴格要求所有屬性名稱都是雙引號,並且字串值也要雙引號。

JSON 新手嘗試使用 JavaScript 文字的程式碼摘錄作為 JSON 是常見的,並且對他們從 JSON 解析器獲得的語法錯誤感到不滿。

當在程式碼或對話中應用不正確的術語時,會出現更多混淆。

常見的反模式是將包含非 JSON 值的變數命名為 json

fetch(url).then(function (response) {
  const json = JSON.parse(response.data); // Confusion ensues!

  // We're done with the notion of "JSON" at this point,
  // but the concept stuck with the variable name.
});

在上面的示例中,response.data 是一些 API 返回的 JSON 字串。JSON 在 HTTP 響應域停止。帶有 jsonmisnomer 的變數只包含一個 JavaScript 值(可能是一個物件,一個陣列,甚至是一個簡單的數字!)

寫上述內容的一種不那麼令人困惑的方式是:

fetch(url).then(function (response) {
  const value = JSON.parse(response.data);

  // We're done with the notion of "JSON" at this point.
  // You don't talk about JSON after parsing JSON.
});

開發人員也傾向於丟擲“JSON 物件”這個短語。這也會導致混淆。因為如上所述,JSON 字串不必將物件儲存為值。 “JSON 字串”是一個更好的術語。就像 XML stringYAML string 一樣。你得到一個字串,你解析它,你最終得到一個值。