此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

View in English Always switch to English

使用 JSON

JavaScript 对象表示法(JSON)是用于将结构化数据表示为 JavaScript 对象的标准格式,通常用于在网站上表示和传输数据(例如从服务器向客户端发送一些数据,因此可以将其显示在网页上)。你会经常遇到它,所以在本文中,我们向你提供使用 JavaScript 处理 JSON 的所有工作,包括访问 JSON 对象中的数据项并编写自己的 JSON。

前提: 具备基本的计算机知识、对 HTML 和 CSS 的基本了解、熟悉 JavaScript 基础知识(阅读 JavaScript 第一步创建代码块)和 JS 面向对象基础(阅读对象介绍)。
目标: 理解 JSON 的数据储存工作原理,创建你的 JSON 对象。

什么是 JSON?

JSON 是一种按照 JavaScript 对象语法的数据格式,这是道格拉斯·克罗克福特推广的。虽然它是基于 JavaScript 语法,但它独立于 JavaScript,这也是为什么许多程序环境能够读取(解读)和生成 JSON。

JSON 可以作为一个对象或者字符串存在,前者用于解读 JSON 中的数据,后者用于通过网络传输 JSON 数据。这不是一个大事件——JavaScript 提供一个全局的 可访问的 JSON 对象来对这两种数据进行转换。

备注:将字符串转换为原生对象称为反序列化(deserialization),而将原生对象转换为可以通过网络传输的字符串称为序列化(serialization)。

一个 JSON 对象可以被储存在它自己的文件中,这基本上就是一个文本文件,扩展名为 .json,还有 application/json MIME 类型

JSON 结构

如上所述,JSON 是一个字符串,其格式非常类似于 JavaScript 对象字面量的格式。你可以在 JSON 中包含与标准 JavaScript 对象相同的基本数据类型——字符串、数字、数组、布尔值和其他对象字面量。这使你可以构建一个数据层次结构,如下所示:

json
{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

如果我们把字符串加载到 JavaScript 程序中,并将其解析到一个名为 superHeroes 的变量,那么我们就可以使用在 JavaScript 对象基础文章中相同的点/括号表示法来访问其中的数据。例如:

js
superHeroes.hometown;
superHeroes["active"];

为了访问层次结构中更深层次的数据,必须将所需的属性名和数组索引链接在一起。例如,访问 members 数组第二个英雄的第三个超能力,可以这样做:

js
superHeroes["members"][1]["powers"][2];
  1. 首先我们有变量名 superHeroes,储存对象。
  2. 在对象中我们想访问 members 属性,所以我们使用 ["members"]
  3. members 包含有对象数组,我们想要访问第二个元素,所以我们使用 [1]
  4. 在对象内,我们想访问 powers 属性,所以我们使用 ["powers"]
  5. powers 属性是一个包含英雄技能的数组。我们想要第三个,所以我们使用 [2]

备注:我们已经在 JSONText.html 实例中让 JSON 对象进入变量中使其可访问(见源代码)。尝试加载它并且在你的浏览器上访问对象数据。

JSON 数组

前面我们提到,JSON 文本基本上看起来像字符串中的 JavaScript 对象。我们也可以将数组与 JSON 相互转换。下面也是有效的 JSON,例如:

json
[
  {
    "name": "Molecule Man",
    "age": 29,
    "secretIdentity": "Dan Jukes",
    "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"]
  },
  {
    "name": "Madame Uppercut",
    "age": 39,
    "secretIdentity": "Jane Wilson",
    "powers": [
      "Million tonne punch",
      "Damage resistance",
      "Superhuman reflexes"
    ]
  }
]

上面是完全合法的 JSON。你只需要通过数组索引就可以访问数组元素,如 [0]["powers"][0]

其他注意事项

  • JSON 是一种纯数据格式,它只包含属性,没有方法。
  • JSON 要求在字符串和属性名称周围使用双引号。单引号无效。
  • 甚至一个错位的逗号或分号就可以导致 JSON 文件出错。你应该小心的检查你想使用的数据(虽然计算机生成的 JSON 很少出错,只要生成程序正常工作)。你可以通过像 JSONLint 这样的应用程序来验证 JSON。
  • JSON 实际上可以是任何可以有效包含在 JSON 中的数据类型的形式。比如,单个字符串或者数字就是有效的 JSON 对象。
  • 与 JavaScript 代码中对象属性可以不加引号不同,JSON 中只有带引号的字符串可以用作属性。

动手练习:一个 JSON 示例

好了,让我们通过运行这个示例来展示我们如何利用 JSON 数据。

开始吧

首先,拷贝我们的 heroes.htmlstyle.css 文件。后者包含了用于页面的简单的 CSS,前者包含了简单的 HTML body,以及一个 <script> 元素,其中包含我们将在练习中编写的 JavaScript 代码:

html
<header>
...
</header>

<section>
...
</section>

<script>
...
</script>

我们已经把 JSON 数据放在了 GitHub 上面:https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json

我们准备把它加载到我们的页面中,然后使用漂亮的 DOM 操作来展示它,就像这样:

顶层函数

顶层函数(top-level function)的代码如下所示:

js
async function populate() {
  const requestURL =
    "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json";
  const request = new Request(requestURL);

  const response = await fetch(request);
  const superHeroes = await response.json();

  populateHeader(superHeroes);
  populateHeroes(superHeroes);
}

为了获取 JSON 数据,我们使用了名为 Fetch 的 API。 该 API 允许我们通过 JavaScript 进行网络请求,从服务器检索资源(如图像、文本、JSON,甚至 HTML 片段),这意味着我们可以仅更新页面的小部分内容而无需重新加载整个页面。

在我们的函数中,前四行使用 Fetch API 从服务器获取 JSON 数据:

  • 我们声明了 requestURL 变量以存储 GitHub 的 URL
  • 我们使用该 URL 初始化一个新的 Request 对象。
  • 我们使用