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 響應域停止。帶有 json
misnomer 的變數只包含一個 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 string
或 YAML string
一樣。你得到一個字串,你解析它,你最終得到一個值。