陣列

在本模組的最後一篇文章中,我們將瞭解陣列——一種將資料項列表儲存在單個變數名下的巧妙方法。在這裡,我們將探討這樣做的好處,然後探索如何建立陣列、檢索、新增和刪除儲存在陣列中的項,以及更多內容。

先決條件 對 HTML 和 CSS 的基本瞭解,以及對 JavaScript 的理解。
目標 瞭解什麼是陣列以及如何在 JavaScript 中操作它們。

什麼是陣列?

陣列通常被描述為“類似列表的物件”;它們基本上是包含儲存在列表中的多個值的單個物件。陣列物件可以儲存在變數中,並且可以像任何其他型別的值一樣處理,區別在於我們可以單獨訪問列表中的每個值,並對列表執行非常有用且高效的操作,例如迴圈遍歷它並對每個值執行相同的操作。也許我們有一系列產品專案及其價格儲存在陣列中,我們希望迴圈遍歷它們並在發票上打印出來,同時計算所有價格的總和並在底部打印出總價。

如果我們沒有陣列,我們將不得不將每個專案儲存在單獨的變數中,然後分別為每個專案呼叫執行列印和新增的程式碼。這樣寫起來會更長、效率更低且更容易出錯。如果我們有 10 個專案要新增到發票中,這已經很煩人了,但是 100 個專案或 1000 個專案呢?我們將在本文後面回到這個示例。

與之前的文章一樣,讓我們透過在瀏覽器開發者控制檯中輸入一些示例來學習陣列的基本知識。

建立陣列

陣列由方括號和用逗號分隔的項組成。

  1. 假設我們要將購物清單儲存在陣列中。將以下程式碼貼上到控制檯中
    js
    const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
    console.log(shopping);
    
  2. 在上面的示例中,每個專案都是一個字串,但在陣列中,我們可以儲存各種資料型別——字串、數字、物件,甚至其他陣列。我們也可以在一個數組中混合資料型別——我們不必將自己限制在在一個數組中只儲存數字,而在另一個數組中只儲存字串。例如
    js
    const sequence = [1, 1, 2, 3, 5, 8, 13];
    const random = ["tree", 795, [0, 1, 2]];
    
  3. 在繼續之前,建立一些示例陣列。

查詢陣列的長度

您可以透過與查詢字串長度(以字元為單位)完全相同的方式查詢陣列的長度(其中包含多少個專案)——使用length 屬性。嘗試以下操作

js
const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
console.log(shopping.length); // 5

訪問和修改陣列項

陣列中的專案編號從零開始。此數字稱為專案的索引。因此,第一個專案的索引為 0,第二個專案的索引為 1,依此類推。您可以使用方括號表示法和提供專案的索引來訪問陣列中的各個專案,就像您訪問字串中的字母一樣。

  1. 將以下內容輸入您的控制檯
    js
    const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
    console.log(shopping[0]);
    // returns "bread"
    
  2. 您還可以透過為單個數組項賦予新值來修改陣列中的項。試試這個
    js
    const shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
    shopping[0] = "tahini";
    console.log(shopping);
    // shopping will now return [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    

    注意:我們之前說過,但作為提醒——JavaScript 從零開始為陣列編制索引!

  3. 請注意,陣列內的陣列稱為多維陣列。您可以透過將兩組方括號連線在一起來訪問陣列內本身位於另一個數組內的項。例如,要訪問random陣列(請參閱上一節)中第三個專案內的陣列中的其中一個專案,我們可以執行以下操作
    js
    const random = ["tree", 795, [0, 1, 2]];
    random[2][2];
    
  4. 在繼續之前,嘗試對您的陣列示例進行更多修改。玩一玩,看看什麼有效,什麼無效。

查詢陣列中項的索引

如果您不知道專案的索引,可以使用indexOf() 方法。indexOf()方法將專案作為引數,並將返回專案的索引或-1(如果專案不在陣列中)。

js
const birds = ["Parrot", "Falcon", "Owl"];
console.log(birds.indexOf("Owl")); //  2
console.log(birds.indexOf("Rabbit")); // -1

新增項

要將一個或多個專案新增到陣列的末尾,我們可以使用push()。請注意,您需要包含一個或多個要新增到陣列末尾的專案。

js
const cities = ["Manchester", "Liverpool"];
cities.push("Cardiff");
console.log(cities); // [ "Manchester", "Liverpool", "Cardiff" ]
cities.push("Bradford", "Brighton");
console.log(cities); // [ "Manchester", "Liverpool", "Cardiff", "Bradford", "Brighton" ]

方法呼叫完成後將返回陣列的新長度。如果要將新陣列長度儲存在變數中,可以執行以下操作

js
const cities = ["Manchester", "Liverpool"];
const newLength = cities.push("Bristol");
console.log(cities); // [ "Manchester", "Liverpool", "Bristol" ]
console.log(newLength); // 3

要將專案新增到陣列的開頭,請使用unshift()

js
const cities = ["Manchester", "Liverpool"];
cities.unshift("Edinburgh");
console.log(cities); // [ "Edinburgh", "Manchester", "Liverpool" ]

刪除項

要從陣列中刪除最後一個專案,請使用pop()

js
const cities = ["Manchester", "Liverpool"];
cities.pop();
console.log(cities); // [ "Manchester" ]

pop()方法返回已刪除的專案。要將該專案儲存在新變數中,可以執行以下操作

js
const cities = ["Manchester", "Liverpool"];
const removedCity = cities.pop();
console.log(removedCity); // "Liverpool"

要從陣列中刪除第一個專案,請使用shift()

js
const cities = ["Manchester", "Liverpool"];
cities.shift();
console.log(cities); // [ "Liverpool" ]

如果您知道專案的索引,則可以使用splice()將其從陣列中刪除

js
const cities = ["Manchester", "Liverpool", "Edinburgh", "Carlisle"];
const index = cities.indexOf("Liverpool");
if (index !== -1) {
  cities.splice(index, 1);
}
console.log(cities); // [ "Manchester", "Edinburgh", "Carlisle" ]

在此對splice()的呼叫中,第一個引數表示從哪裡開始刪除專案,第二個引數表示應刪除多少個專案。因此,您可以刪除多個專案

js
const cities = ["Manchester", "Liverpool", "Edinburgh", "Carlisle"];
const index = cities.indexOf("Liverpool");
if (index !== -1) {
  cities.splice(index, 2);
}
console.log(cities); // [ "Manchester", "Carlisle" ]

訪問每個項

很多時候,您需要訪問陣列中的每個專案。您可以使用for...of語句來執行此操作

js
const birds = ["Parrot", "Falcon", "Owl"];

for (const bird of birds) {
  console.log(bird);
}

有時您希望對陣列中的每個專案執行相同的操作,從而得到一個包含已更改專案的陣列。您可以使用map()來執行此操作。以下程式碼獲取一個數字陣列,並將每個數字加倍

js
function double(number) {
  return number * 2;
}
const numbers = [5, 2, 7, 6];
const doubled = numbers.map(double);
console.log(doubled); // [ 10, 4, 14, 12 ]

我們將一個函式傳遞給map(),並且map()為陣列中的每個專案呼叫該函式一次,並將專案作為引數傳遞。然後,它將每次函式呼叫的返回值新增到一個新陣列中,最後返回該新陣列。

有時您希望建立一個新陣列,其中只包含原始陣列中與某些測試匹配的專案。您可以使用filter()來執行此操作。以下程式碼獲取一個字串陣列,並返回一個僅包含長度大於 8 個字元的字串的陣列

js
function isLong(city) {
  return city.length > 8;
}
const cities = ["London", "Liverpool", "Totnes", "Edinburgh"];
const longer = cities.filter(isLong);
console.log(longer); // [ "Liverpool", "Edinburgh" ]

map()一樣,我們將一個函式傳遞給filter()方法,並且filter()為陣列中的每個專案呼叫此函式,並將專案作為引數傳遞。如果函式返回true,則將該專案新增到一個新陣列中。最後,它返回該新陣列。

在字串和陣列之間轉換

通常,您會看到一些包含在一個很長的字串中的原始資料,並且您可能希望將有用的專案分離到更方便的形式中,然後對其進行操作,例如在資料表中顯示它們。為此,我們可以使用split()方法。在其最簡單的形式中,它接受一個引數,即您想要在其中分隔字串的字元,並將分隔符之間的子字串作為陣列中的專案返回。

注意:好的,從技術上講,這是一種字串方法,而不是陣列方法,但我們將其與陣列一起放在這裡,因為它很適合在這裡。

  1. 讓我們一起操作一下,看看它是如何工作的。首先,在您的控制檯中建立一個字串
    js
    const data = "Manchester,London,Liverpool,Birmingham,Leeds,Carlisle";
    
  2. 現在讓我們在每個逗號處拆分它
    js
    const cities = data.split(",");
    cities;
    
  3. 最後,嘗試查詢新陣列的長度並從中檢索一些專案
    js
    cities.length;
    cities[0]; // the first item in the array
    cities[1]; // the second item in the array
    cities[cities.length - 1]; // the last item in the array
    
  4. 您還可以使用join()方法反過來操作。嘗試以下操作
    js
    const commaSeparated = cities.join(",");
    commaSeparated;
    
  5. 將陣列轉換為字串的另一種方法是使用toString()方法。toString()可以說比join()更簡單,因為它不帶引數,但更受限制。使用join(),您可以指定不同的分隔符,而toString()始終使用逗號。(嘗試使用與逗號不同的字元執行步驟 4。)
    js
    const dogNames = ["Rocket", "Flash", "Bella", "Slugger"];
    dogNames.toString(); // Rocket,Flash,Bella,Slugger
    

主動學習:列印這些產品

讓我們回到我們之前描述的示例——在發票上打印出產品名稱和價格,然後計算價格總和並在底部打印出來。在下面的可編輯示例中,有一些包含數字的註釋——每個註釋都標記了一個必須向程式碼中新增內容的位置。它們如下所示

  1. // number 1註釋下方,有一些字串,每個字串都包含用冒號分隔的產品名稱和價格。我們希望您將其轉換為陣列並將其儲存在名為products的陣列中。
  2. // number 2註釋下方,開始一個for...of()迴圈以遍歷products陣列中的每個專案。
  3. // number 3註釋下方,我們希望您編寫一行程式碼,將當前陣列項(name:price)拆分為兩個單獨的專案,一個只包含名稱,另一個只包含價格。如果您不確定如何執行此操作,請參閱有用的字串方法文章以獲取幫助,或者更好的是,檢視本文的字串和陣列之間的轉換部分。
  4. 作為上述程式碼的一部分,您還需要將價格從字串轉換為數字。如果您不記得如何執行此操作,請檢視第一篇字串文章
  5. 有一個名為total的變數,它在程式碼頂部建立並賦值為 0。在迴圈內(在// number 4下方),我們希望您新增一行程式碼,在迴圈的每次迭代中將當前專案價格新增到該總計中,以便在程式碼結束時將正確的總計列印到發票上。您可能需要一個賦值運算子來執行此操作。
  6. 我們希望您更改// number 5正下方的行,以便使itemText變數等於“當前專案名稱 - $當前專案價格”,例如“鞋子 - $23.99”,以便在每種情況下在發票上打印出每個專案的正確資訊。這只是一個簡單的字串連線,您應該熟悉它。
  7. 最後,在// number 6註釋下方,您需要新增一個}以標記for...of()迴圈的結束。

主動學習:前 5 名搜尋

push()pop()這樣的陣列方法的一個很好的用途是在維護 Web 應用程式中當前活動專案的記錄時。例如,在動畫場景中,您可能有一個表示當前顯示的背景圖形的物件陣列,並且出於效能或避免混亂的原因,您可能只想一次顯示 50 個。隨著新物件的建立和新增到陣列中,可以從陣列中刪除舊的物件以維持所需的數量。

在此示例中,我們將展示一個更簡單的用途——在這裡,我們為您提供了一個假的搜尋網站,帶有一個搜尋框。其想法是,當在搜尋框中輸入術語時,前 5 個以前的搜尋術語將顯示在列表中。當術語數量超過 5 時,每次將新術語新增到頂部時,最後一個術語將開始被刪除,因此始終顯示前 5 個以前的術語。

注意:在真實的搜尋應用程式中,您可能能夠點選以前的搜尋術語以返回到以前的搜尋,並且它將顯示實際的搜尋結果!我們現在只是保持簡單。

要完成該應用程式,我們需要您

  1. // number 1註釋下方新增一行程式碼,將當前輸入到搜尋輸入中的值新增到陣列的開頭。可以使用searchInput.value檢索它。
  2. // number 2註釋下方新增一行程式碼,刪除當前位於陣列末尾的值。

測試你的技能!

您已經閱讀完本文,但您還記得最重要的資訊嗎?在繼續學習之前,您可以進行一些額外的測試來驗證您是否保留了這些資訊——請檢視測試您的技能:陣列

結論

閱讀完本文後,我們相信您會同意陣列非常有用;您會在 JavaScript 中隨處可見它們,通常與迴圈結合使用,以便對陣列中的每個專案執行相同的操作。在下一模組中,我們將教授您關於迴圈的所有有用的基礎知識,但現在您應該給自己鼓掌並休息一下;您已經完成了本模組的所有文章!

剩下的唯一事情就是完成本模組的評估,這將測試您對之前文章的理解。

另請參閱

  • 索引集合——關於陣列及其近親型別化陣列的高階指南。
  • Array——Array 物件參考頁面——詳細的參考指南,涵蓋了本頁中討論的功能,以及更多其他功能。