為什麼一個值永遠不夠
到目前為止,你可能一次只存一樣東西:一個名字、一個價格、一個數字。變數就像一個貼了標籤的盒子,裡面恰好裝一樣東西。在真實世界出現之前,這都很好用,因為真實世界幾乎從不只有一件東西。
想想一張購物清單、一個班級的學生,或者一個播放清單裡的歌曲。它們每一個都是一堆屬於同一組的值。你可以為每一項單獨建一個變數,但如果有二十項,那就意味著要命名、追蹤和記住二十個盒子。
這正是集合要解決的問題。你不再需要許多分開的盒子,而是得到一個容器,把所有相關的值都裝在一起,並給這個容器起一個名字。你最常用的兩種容器就是陣列和物件。
陣列:一個有序列表
陣列是一串放在同一個名字下、有順序的值。想像一排編了號的置物櫃:順序是固定的,每個值都待在自己的格子裡。你用方括號來寫它,用逗號分隔各項。
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 就是同樣的結構寫成的文字,程式就是用它來交換資料的。
一旦這兩種形態對你來說變得自然,程式設計的大部分就成了為你的資料選對容器、然後走訪它。這是一大步,而你剛剛邁出了它。