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
一样。你得到一个字符串,你解析它,你最终得到一个值。