馬維君 (Grete Ma) 已發佈 2019-10-12

Cheatsheet for Array Methods - JavaScript 陣列方法大全

你是學完基礎 JavaScript 後,還對陣列懵懵懂懂的人嗎?或是你大概知道陣列是儲存資料用的,但用來用去都是 length 取長度、.push() 增加資料?
不管你是哪種人,只要你對陣列方法不熟悉,你就很適合閱讀本文。
如果你喜好閱讀文件又不嫌眼睛疲勞,那就更適合了。


在這篇文章中,我選了較常遇到的 26 個陣列方法來介紹,並且將之分為三大類,分別為:

  • 修改原始陣列的方法

    copyWithin()、fill()、pop()、push()、reverse()、shift()、unshift()、sort()、splice()

  • 取得陣列而不會更動原始陣列的方法

    (回傳陣列元素資訊、索引值、某個值、或產生新的陣列)

    concat()、includes()、indexOf()、lastIndexOf()、join()、slice()、toString()

  • 對陣列內每個元素進行同樣處理的方法(疊代)

    entries()、keys()、values()、every()、some()、filter()、find()、forEach()、map()、reduce()

以下將一一介紹這些陣列方法。


修改陣列的方法 Mutator methods

本類別的方法可以變更原始陣列。

copyWithin()

複製陣列中的元素,並置換原始陣列中原本的元素。

參數

有三個參數:

  • 第一個是要置換的位置(必填)。
  • 第二個是複製起點的索引值(選填)。
  • 第三個是複製終點的索引值 + 1(選填)。

如果省略第二個參數,則會從陣列第一個元素開始複製。
如果省略第三個參數,則會複製到陣列最後一個元素為止。
使用此方法處理後的陣列長度必須等於原本的長度,如果超過原本長度,則超過的部分不予顯示。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
// 從木瓜開始置換,從香蕉開始複製到芭樂
fruits.copyWithin(3,1,4);
console.log(fruits);
//  ["蘋果", "香蕉", "芭樂", "香蕉", "芭樂"]
// 「香蕉 芭樂」 取代了 「木瓜 番茄」

let fruits2 = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
// 從木瓜開始置換,從蘋果開始複製到芭樂
fruits2.copyWithin(3, 0, 4);
console.log(fruits2);
// ["蘋果", "香蕉", "芭樂", "蘋果", "香蕉"]
// 置換後的陣列長度必須跟原本相同,所以雖然有複製到芭樂,但只顯示到香蕉為止

fill()

用一個指定的值置換陣列中所有元素。

參數

有三個參數:

  • 第一個是指定要置換的值(必填)。
  • 第二個是置換起點的索引值(選填,預設為 0,即置換全部)。
  • 第三個是置換終點的索引值 + 1(選填,預設等於陣列長度)。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

// 索引值 2 跟 3 的值置換為「釋迦」
console.log(fruits.fill('釋迦', 2, 4));
// ["蘋果", "香蕉", "釋迦", "釋迦", "番茄"]

// 從索引值 1 開始的值置換為「鳳梨」
console.log(fruits.fill('鳳梨', 1));
// ["蘋果", "鳳梨", "鳳梨", "鳳梨", "鳳梨"]

// 將陣列所有元素的值置換為「柳丁」
console.log(fruits.fill('柳丁'));
// ["柳丁", "柳丁", "柳丁", "柳丁", "柳丁"]

pop()

從陣列中刪除最後一個元素並回傳該元素。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
// 刪除並回傳最後面的元素
console.log(fruits.pop());
// "番茄"

// 檢查原陣列
console.log(fruits);
// ["蘋果", "香蕉", "芭樂", "木瓜"]

溫馨提示:跟下面的 shift() 剛好相反,可以一起記。

push()

在陣列尾端加入一個或數個元素,並回傳修改後的陣列。

範例

let fruits = ['蘋果', '香蕉'];
// 增加一個資料
fruits.push('芭樂');
console.log(fruits);
// ["蘋果", "香蕉", "芭樂"]

// 繼續增加數個資料
fruits.push('木瓜', '番茄');
console.log(fruits);
// ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

溫馨提示:跟下面的 unshift() 剛好相反,可以一起記。

reverse()

反轉陣列元素的順序,原本第一個元素成為最後一個,而原本最後一個元素成為第一個。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
fruits.reverse();
console.log(fruits);
// ["番茄", "木瓜", "芭樂", "香蕉", "蘋果"]

shift()

從陣列中刪除第一個元素並回傳該元素。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
console.log(fruits.shift());  // "蘋果"
console.log(fruits);  // ["香蕉", "芭樂", "木瓜", "番茄"]

溫馨提示:跟 pop() 剛好相反,可以一起記。

unshift()

在陣列前端加入指定的一個或數個元素,並回傳修改後的陣列及新長度。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

// 增加一個資料
console.log(fruits.unshift('檸檬'));
console.log(fruits);
// 6
// ["檸檬", "蘋果", "香蕉", "芭樂", "木瓜", "番茄"]

// 增加數個資料
fruits2 = fruits; // 拷貝上面的陣列,不是重點,請別在意
console.log(fruits2.unshift('柳丁', '橘子'));
console.log(fruits2);
// 8
// ["柳丁", "橘子", "檸檬", "蘋果", "香蕉", "芭樂", "木瓜", "番茄"]

溫馨提示:跟 push() 剛好相反,可以一起記。

sort()

對陣列的元素進行排序並回傳陣列。

參數

此方法需要指定一個函式作為參數來定義陣列內的排序,且函式包含兩個參數,以 ab 為例,若 a - b < 0,則 a 會排在 b 前面;若 a - b > 0,則 a 會排在 b 的後面;若 a - b = 0,則 ab 兩者的排序不會變動,但會跟全部的元素一起比較來排序。
假如省略函式參數,陣列會將各個元素轉為字串,並根據每一個字元的 Unicode 進行排序。

範例

// 指定函式參數的例子 1
let nums = [99, 999, 88, 888, 666];
nums.sort(function(a, b) {
  return a - b; // 由小到大排列
});
console.log(nums);
// [88, 99, 666, 888, 999]

// 指定函式參數的例子 2
let nums = [99, 999, 88, 888, 666];
nums.sort(function(a, b) {
  return b - a; // 由大到小排列
});
console.log(nums);
// [999, 888, 666, 99, 88]

// 沒指定函式參數的例子
let nums = [99, 999, 88, 888, 666];
nums.sort();
console.log(nums);
// [666, 88, 888, 99, 999]

溫馨提示:Vue 課程中有章節作業需要使用此方法哦 ^^

splice()

移除或取代陣列中的元素。

參數

包含了三個參數:

  • 第一個是要改動的元素索引值(必填)。
  • 第二個是要移除的總筆數(選填),若省略,則從刪除起點開始的所有元素都會被刪除;若設定為 0 或負數,則不會有元素被移除。
  • 第三個是要添加的內容(選填),若省略,則原陣列資料不會被新資料替換,也就是單純刪除陣列資料的意思。

範例

// 從芭樂開始,刪除一筆資料
let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
fruits.splice(2,1);
console.log(fruits);
// ["蘋果", "香蕉", "木瓜", "番茄"]

// 指定第三個參數,取代原本的資料
let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
// 從芭樂開始,替換一筆資料為釋迦
fruits.splice(2,1,'釋迦');
console.log(fruits);
// ["蘋果", "香蕉", "釋迦", "木瓜", "番茄"] 

溫馨提示:小心不要跟 slice() 搞混囉~


取得陣列的方法 Accessor methods

本類別的方法不會修改到原始陣列,而是以某些表現形式回傳值或新陣列。

concat()

用來合併數個陣列,會回傳一個合併後的新陣列,且不會更改到原始的陣列。

範例

let fruits1 = ['蘋果', '香蕉', '芭樂'];
let fruits2 = ['木瓜', '番茄'];
let fruits3 = fruits1.concat(fruits2);

console.log(fruits3);  // ["蘋果", "香蕉", "芭樂", "木瓜", "番茄"]

// 兩個原陣列不變
console.log(fruits1);  // ["蘋果", "香蕉", "芭樂"]
console.log(fruits2);  // ["木瓜", "番茄"]

includes()

確定陣列是否包含特定元素,並根據結果回傳 truefalse

參數

有兩個參數:

  • 第一個參數為要判斷的值(必填)。
  • 第二個參數為搜尋起點的索引值(選填),此參數如果設定為負數,那麼搜尋起點將會是陣列長度 + 此參數的值。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
let isGuava = fruits.includes('芭樂');
let isVa = fruits.includes('樂');
let over = fruits.includes('芭樂', 3);
let minus = fruits.includes('芭樂', -5);

console.log(isGuava); // true
console.log(isVa); // false
console.log(over); // false,從索引值 3 開始找,找不到芭樂
console.log(minus); // true,5 + (-5) = 0,從索引值 0 開始找

indexOf()

在陣列中搜尋指定元素,將會回傳第一個符合條件的元素的索引值;若在陣列中沒找到,則回傳 -1。

參數

有兩個參數:

  • 第一個參數為要判斷的值(必填)。
  • 第二個參數為搜尋起點的索引值(選填,預設為 0)。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '芭樂', '番茄'];

console.log(fruits.indexOf('香蕉'));
// 1,代表元素在索引值 1

console.log(fruits.indexOf('芭樂'));
// 2,只會回傳第一個符合的元素索引值

console.log(fruits.indexOf('榴槤'));
// -1,陣列中無此資料

console.log(fruits.indexOf('香蕉',3));
// -1,從索引值 3 開始找,沒找到

lastIndexOf()

在陣列中搜尋指定元素,將會回傳最後一個符合條件的元素的索引值,若在陣列中沒找到則回傳 -1。

參數

有兩個參數:

  • 第一個參數為要判斷的值(必填)。
  • 第二個參數為由後向前搜尋的起點索引值(選填,預設全部搜尋)。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '芭樂', '番茄'];

console.log(fruits.lastIndexOf('芭樂')); // 3,只會回傳最後一個符合的元素索引值
console.log(fruits.lastIndexOf('香蕉',3)); // 1,從索引值 3 往回找,元素在索引值 1

join()

會將陣列中的元素用指定字串或符號連接成一個字串,並回傳連接後的字串。

參數

含一個參數:即指定字串、符號。若沒有指定字串,預設會用 , 合併。如果指定用 '' 連接陣列資料,則會回傳一個緊貼無空白的字串。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

console.log(fruits.join());
// "蘋果,香蕉,芭樂,木瓜,番茄"
console.log(fruits.join('~~'));
// "蘋果~~香蕉~~芭樂~~木瓜~~番茄"
console.log(fruits.join('好吃!'));
// "蘋果好吃!香蕉好吃!芭樂好吃!木瓜好吃!番茄",抱歉了番茄...
console.log(fruits.join(''));
// "蘋果香蕉芭樂木瓜番茄"

slice()

用索引值選取起點到終點,就可以複製該範圍(不含終點)的元素並回傳一個新陣列。

參數

有兩個參數:

  • 第一個是起點索引值。
  • 第二個是終點索引值 + 1。
    值得一提的是,兩個參數均非必填,如果忽略的話,將會複製整個原始陣列。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
// 兩個參數均填入
let cutFruits = fruits.slice(3,5);
console.log(cutFruits);
// ["木瓜", "番茄"]

// 忽略兩個參數
let sameFruits = fruits.slice();
console.log(sameFruits);
// ["蘋果", "香蕉", "芭樂", "木瓜", "番茄"]

溫馨提示:小心不要跟 splice() 搞混囉~

toString()

將陣列以字串方式回傳。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];
console.log(fruits.toString());
// "蘋果,香蕉,芭樂,木瓜,番茄"

陣列疊代的方法 Iteration methods

什麼是疊代?

疊代指的是對物件重複同樣的處理方法,每重複一次就稱為一次疊代。JavaScript 中的疊代大部分指的是迴圈,但陣列中也有類似迴圈功能的方法,這些方法會產生「疊代器」來達成類似迴圈的效果。

帶有函式參數的陣列方法

有些方法在處理陣列時,會使用回呼函式作為參數。這些方法會採樣原始陣列的長度,而在回呼中被加入的元素則不會被巡訪。所以如果你需要更改陣列,還是應該先複製一個新陣列來操作。

回傳疊代器物件的陣列方法

有些方法回傳的不是新陣列或是特定的值,而是一個陣列疊代器物件,而要操作或讀取該物件的值就需要使用 for...of 語法。for...of 的用法是這樣的:

for ( let 要疊代的元素 of 疊代器){
  要對元素做的事;
}

參照:[筆記] JavaScript ES6 中的 for ... of(處理陣列的好幫手)

entries()

回傳一個新的陣列疊代器物件,裡面包含陣列中索引值與元素的配對,需要使用 for...of 來讀取疊代器的值。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

// 將回傳的疊代器用變數 iterator 儲存
let iterator = fruits.entries();
// 使用 for...of
for(let value of iterator){
  console.log(value);
}
/*
[0, "蘋果"]
[1, "香蕉"]
[2, "芭樂"]
[3, "木瓜"]
[4, "番茄"]
*/

keys()

回傳一個新的陣列疊代器物件,裡面包含陣列中的每一個索引值,需要使用 for...of 來讀取疊代器的值。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

// 將回傳的疊代器用變數 iterator 儲存
let iterator = fruits.keys();
// 使用 for...of
for(let value of iterator){
  console.log(value);
}
// 依序出現: 0 1 2 3 4

values()

回傳一個新的陣列疊代器物件,該物件包含陣列中每個元素的值。需要使用 for...of 來讀取疊代器的值。

範例

let fruits = ['蘋果', '香蕉', '芭樂', '木瓜', '番茄'];

// 將回傳的疊代器用變數 iterator 儲存
let iterator = fruits.values();
// 使用 for...of
for(let fruitsName of iterator){
  console.log(fruitsName);
}
// 依序出現:"蘋果" "香蕉" "芭樂" "木瓜" "番茄"

every()

如果此陣列中的每個元素都滿足回呼函式給的條件,則回傳 true,如果有任何一個不符合條件,則回傳 false

參數

  • 含有一個參數,此參數為 callback 函式。
  • 函式中有一個必填的參數,這個參數用來代表陣列中每個需要被疊代的元素。
  • 函式中的 return 後面接著的是要判斷的條件。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];

// 條件:字元數大於 2
let ans = fruits.every(function(el){
  return el.length > 2 ;
});
console.log(ans); // true

// 條件:字元數大於 5
let ans2 = fruits.every(function(el){
  return el.length > 5 ;
});
console.log(ans2); // false

some()

陣列中至少有一個元素滿足回呼函式的條件,就會返回 true,如果全部元素都不符合條件,則回傳 false

參數

  • 含有一個參數,此參數為 callback 函式。
  • 函式中有一個必填參數及三個選填參數:
    • 每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
    • 執行此函式的 this 值(選填)。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];

// 條件:字元數大於 5
let ans1 = fruits.some(function(el){
  return el.length > 5 ;
});
console.log(ans1); // true

// 條件:字元數大於 6
let ans2 = fruits.some(function(el){
  return el.length > 6 ;
});
console.log(ans2); // false

filter()

使用此方法給定條件,就能將符合條件的元素從陣列中過濾出來,過濾出來的元素會以一個陣列的形式回傳。

參數

  • 含有一個參數,此參數為 callback 函式。
  • 函式中有一個必填參數及三個選填參數:
    • 每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
    • 執行此函式的 this 值(選填)。
  • 函式中的 return 後面接著的是要判斷的條件。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];

// 過濾出字元數大於 5 的值
let ans = fruits.filter(function(el){
  return el.length > 5 ;
});
console.log(ans);
// ["banana", "papaya", "tomato"]

溫馨提示:好用哦!可以的話請記起來 ^^

find()

回傳第一個滿足條件的值,如果找不到則回傳 undefined

參數

  • 含有一個參數,此參數為 callback 函式。
  • 函式中有一個必填參數及三個選填參數:
    • 每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
    • 執行此函式的 this 值(選填)。
  • 函式中的 return 後面接著的是要判斷的條件。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];

let ans = fruits.find(function(el){
  // 找出字元數大於 5 的值
  return el.length > 5 ;
});
console.log(ans);
// "banana"(答案有三個,但只會回傳第一個)

forEach()

將陣列內的每個元素,皆傳入給定的函式並執行。

參數

  • 含有一個參數,此參數為 callback 函式。
  • 函式中有一個必填參數及三個選填參數:
    • 每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
    • 執行此函式的 this 值(選填)。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];
let str = '';
fruits.forEach(function(el){
  str += 'tasty ' + el + ', ';  
});
console.log(str);
// "tasty apple, tasty banana, tasty guava, tasty papaya, tasty tomato, "

上面這一段語法如果用 for 迴圈來寫的話,會是長這樣:

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];
let str = '';
for (let i=0; i < fruits.length ; i++) {
  str += 'tasty ' + fruits[i] + ', ';  
}
console.log(str);
// 結果是一樣的

forEach() 無法用 break 中斷,如果想要中斷執行的話要使用傳統的 for 迴圈。

溫馨提示:Vue 中有很重要的指令是基於 forEach() 設計的,大家要記得哦。

map()

建立一個新的陣列,其內容為原陣列的每一個元素經由函式運算後所回傳的結果。

參數

此方法有兩個參數:

  • callback 函式(必填),函式又有三個參數:
    • 陣列中每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
  • 執行此函式的 this 值(選填)。

範例

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];
let fruits2 = fruits.map(function(el){
  el = 'tasty '+ el; // 每個陣列元素前面都加上 'tasty'
  return el;  // 回傳處理過後的陣列元素
});

console.log(fruits2);
// ["tasty apple", "tasty banana", "tasty guava", "tasty papaya", "tasty tomato"]

注意,使用 map() 回傳新陣列時,新陣列的長度必須等於原始陣列長度,如果新陣列長度不足,缺少的位置則會產生 undefined 值。

let fruits = ['apple', 'banana', 'guava', 'papaya', 'tomato'];
let fruits2 = fruits.map(function(el){
  if (el.length > 5) {
    // 回傳字元長度大於 5 的值
    return el;
  }
});
console.log(fruits2);
// [undefined, "banana", undefined, "papaya", "tomato"]

reduce()

將陣列中每個元素傳入函式中進行計算,每次計算的結果會再與下個元素作計算,最後將陣列化為單一個值,適合用於累加與比對。

參數

此方法有兩個參數:

  • callback 函式(必填),函式又有四個參數:
    • 累加器,用來累積函式每一次執行的回傳值(必填)。
    • 每個被疊代的元素(必填)。
    • 目前處理的元素索引值(選填)。
    • 使用該方法的陣列(選填)。
  • 執行計算時的第一個數值(選填,預設為陣列第一個值,可傳入別的值)。

範例

// 累加陣列內所有值
let classmate = [
  {
    name: 'Steffi',
    tall: 160
  },
  {
    name: 'Lala',
    tall: 168
  },
  {
    name: 'Paul',
    tall: 176
  }
];

let tallPlus = classmate.reduce(function(plus, el){
  // 將每個人的身高與前一個人相加
  return plus + el.tall;
}, 0);

console.log(tallPlus);
// 504

參考資料

Array - JavaScript | MDN
JavaScript Array 陣列操作方法大全 ( 含 ES6 )
[JS] JavaScript 疊代與迴圈(iterate and loop) | PJCHENder 私房菜
[JS] JavaScript 疊代器(Iterator) | PJCHENder 私房菜
鐵人賽:常用陣列方法 | 卡斯伯 Blog - 前端,沒有極限


以上就是我整理的 26 個陣列方法!給看到最後的看倌鼓鼓掌~
雖然本文並沒有囊括所有的陣列方法,但我想應該很夠用了,希望能夠多少幫助各位在處理資料上更有效率。
如果還看得意猶未盡的話(?),可以延伸閱讀文末的參考資料,全部都是優質好文哦!

關於筆者

暱稱:馬維君 (Grete Ma)

介紹:前公務員,現在則是在技術沙漠中拓荒的前端初心者。 技術部落格:https://medium.com/馬格蕾特的冒險者日誌

文章列表 文章列表