为什么一个值永远不够
到目前为止,你可能一次只存一样东西:一个名字、一个价格、一个数字。变量就像一个贴了标签的盒子,里面恰好装一样东西。在真实世界出现之前,这都很好用,因为真实世界几乎从不只有一件东西。
想想一张购物清单、一个班级的学生,或者一个播放列表里的歌曲。它们每一个都是一堆属于同一组的值。你可以为每一项单独建一个变量,但如果有二十项,那就意味着要命名、追踪和记住二十个盒子。
这正是集合要解决的问题。你不再需要许多分开的盒子,而是得到一个容器,把所有相关的值都装在一起,并给这个容器起一个名字。你最常用的两种容器就是数组和对象。
数组:一个有序列表
数组是一串放在同一个名字下、有顺序的值。想象一排编了号的储物柜:顺序是固定的,每个值都待在自己的格子里。你用方括号来写它,用逗号分隔各项。
let fruits = ["apple", "banana", "cherry"]; console.log(fruits[0]); // "apple" console.log(fruits[2]); // "cherry"
要把某个值取出来,你要给出它的位置,这个位置叫做索引(index)。对初学者来说唯一令人意外的是,计数从 0 开始,而不是 1。所以第一种水果在索引 0,第二种在索引 1,第三种在索引 2。
对象:命名的抽屉
有时候用位置来组织东西并不合适。如果你要描述一个人,「第 1 项」和「第 2 项」什么也说明不了。你想要的是像姓名、年龄、城市这样的标签。这正是对象提供的。
对象就是一组贴了标签的抽屉。每个抽屉有一个键(key,也就是标签)和一个值(value,也就是里面装的东西)。你用花括号来写它,每一对写成 `key: value`。要取一个值,你按名字去要,而不是按编号。
let person = {
name: "Mei",
age: 28,
city: "Taipei"
};
console.log(person.name); // "Mei"
console.log(person.city); // "Taipei"这就是清晰的对比。数组问「哪个位置?」,用 `fruits[0]` 回答。对象问「哪个标签?」,用 `person.name` 回答。一串有序的同类东西用数组;一个东西的若干命名细节用对象。
嵌套与 JSON
当你把这些容器互相嵌套时,真正的威力就显现出来了。对象里的某个值本身可以是一个数组,数组里的某一项本身也可以是一个对象。这叫做嵌套(nesting),它让你几乎可以表示任何东西。
let student = {
name: "Mei",
grades: [88, 92, 79],
address: { city: "Taipei", zip: "100" }
};
console.log(student.grades[1]); // 92
console.log(student.address.city); // "Taipei"读取嵌套数据无非就是顺着路径走。`student.grades[1]` 的意思是:进入 student,再进入 grades 数组,然后取位置 1。你把点和方括号一段段接起来,直到落在你要的值上。
现在说回报。当你把这种嵌套结构原封不动地写成纯文本时,你得到的就是 JSON(JavaScript Object Notation,JavaScript 对象表示法)。JSON 是程序之间互相传递这些集合的方式,比如网站向服务器请求数据时。它看起来几乎和上面的对象一模一样,只是写成了文本。
把它们串起来
你从单个盒子开始,很快就不够用了。集合给了你能在一个名字下装许多相关值的容器,其中两种承担了大部分工作。
- 用数组来装有序列表,通过位置取出每一项,从 0 开始数。
- 用对象来打包一个东西的若干命名细节,通过键取出每个值。
- 自由地嵌套它们,然后顺着点和方括号的路径读取值。
- 认出 JSON 就是同样的结构写成的文本,程序就是用它来交换数据的。
一旦这两种形态对你来说变得自然,编程的大部分就成了为你的数据选对容器、然后遍历它。这是一大步,而你刚刚迈出了它。