本文 AI 產出,尚未審核

JavaScript 陣列操作:includesindexOflastIndexOf

簡介

在日常開發中,陣列是最常見的資料結構之一。無論是處理使用者輸入、API 回傳資料,還是實作演算法,都離不開對陣列的搜尋與判斷。JavaScript 為我們提供了三個非常實用的原生方法:includesindexOf 以及 lastIndexOf。它們分別用於判斷元素是否存在取得第一個匹配元素的索引,以及取得最後一個匹配元素的索引。掌握這三個方法,能讓你在寫程式時少寫迴圈、減少錯誤,並提升程式的可讀性與效能。

本篇文章將以淺顯易懂的語言,從概念說明、實作範例、常見陷阱,到最佳實踐與真實應用場景,完整介紹 includesindexOflastIndexOf 的使用方式。即使你是剛踏入 JavaScript 的新手,也能快速上手;若你已具備一定基礎,亦能從中發掘更進階的技巧。


核心概念

1. Array.prototype.includes(value, fromIndex?)

includes 會檢查陣列中是否 至少出現一次 指定的 value,回傳布林值 truefalse。第二個參數 fromIndex(可選)表示搜尋起始位置,支援負數表示從陣列尾端往前算。

特點

  • 直接回傳 布林,不需要再比較索引。
  • 使用 嚴格相等(===) 進行比較,NaN 也是例外(includes 能正確偵測 NaN)。
  • 讀寫簡潔,適合 是否存在 的判斷。

範例 1:基本用法

const fruits = ['apple', 'banana', 'orange'];

console.log(fruits.includes('banana'));   // true
console.log(fruits.includes('grape'));    // false

範例 2:從指定位置開始搜尋

const numbers = [1, 2, 3, 2, 1];

console.log(numbers.includes(2, 2)); // true  // 從索引 2 開始,找到最後一個 2
console.log(numbers.includes(1, -2)); // false // 從倒數第二個元素往前找,找不到 1

範例 3:偵測 NaN

const mixed = [0, NaN, undefined];

console.log(mixed.includes(NaN)); // true

2. Array.prototype.indexOf(searchElement, fromIndex?)

indexOf 會回傳 第一個 出現 searchElement 的索引,若找不到則回傳 -1。同樣支援 fromIndex,負數會從陣列尾端計算起始位置。

特點

  • 回傳 索引,適合需要知道元素位置的情況。
  • 使用 嚴格相等(===),但 無法偵測 NaN(因為 NaN !== NaN)。
  • 在字串或類似陣列的物件(如 arguments)上也可使用。

範例 4:基本搜尋

const colors = ['red', 'green', 'blue', 'green'];

console.log(colors.indexOf('green')); // 1   (第一個 green 的位置)
console.log(colors.indexOf('yellow')); // -1

範例 5:指定起始索引

const letters = ['a', 'b', 'c', 'b', 'a'];

console.log(letters.indexOf('b', 2)); // 3   // 從索引 2 開始找,回傳後面的 b

範例 6:NaN 無法偵測

const arr = [NaN, 1, 2];
console.log(arr.indexOf(NaN)); // -1   // 因為 NaN !== NaN

3. Array.prototype.lastIndexOf(searchElement, fromIndex?)

lastIndexOfindexOf 相似,但它會 從右至左(即從陣列尾端)搜尋,回傳最後一次出現的索引;若找不到則回傳 -1。同樣支援 fromIndex,負數會從尾端往左算起。

特點

  • 用於 取得最後一次出現 的位置。
  • 同樣使用 嚴格相等,無法偵測 NaN
  • 常見於需要去除重複元素、或找出最近的匹配項目。

範例 7:基本用法

const nums = [5, 10, 15, 10, 20];

console.log(nums.lastIndexOf(10)); // 3   // 最後一個 10 的索引
console.log(nums.lastIndexOf(30)); // -1

範例 8:搭配 fromIndex

const data = [1, 2, 3, 2, 1];

console.log(data.lastIndexOf(2, 2)); // 1   // 只搜尋到索引 2 為止

範例 9:NaN 無法偵測

const weird = [NaN, 0, NaN];
console.log(weird.lastIndexOf(NaN)); // -1

常見陷阱與最佳實踐

陷阱 說明 建議的解決方式
indexOflastIndexOf 無法偵測 NaN NaN !== NaN,因此這兩個方法找不到 NaN 若需要檢測 NaN,改用 includes 或自行使用 Array.prototype.some
忽略 fromIndex 的負數行為 負數會從陣列尾端算起,若不熟悉會產生錯誤結果。 在使用前先檢查 fromIndex 的意圖,或使用 Array.prototype.slice 產生子陣列再搜尋。
使用 indexOf 判斷存在性 直接比較 !== -1 雖可行,但可讀性較差。 建議使用 includes,語意更清晰。
搜尋物件或陣列時的相等性 只能比較同一個參考,不同但內容相同的物件不會匹配。 若要深度比較,需自行實作或使用 lodash.isEqual 等工具函式。
大陣列的效能 includesindexOflastIndexOf 都是 線性搜尋,最壞情況 O(n)。 若搜尋頻繁且陣列很大,考慮使用 SetMap 或建立索引結構。

最佳實踐

  1. 語意優先:判斷「是否存在」時,優先使用 includes;需要索引時才使用 indexOf / lastIndexOf
  2. 避免硬編碼 -1:可寫成 if (arr.includes(item)),或封裝成 function contains(arr, val){ return arr.includes(val); },提升可讀性。
  3. 結合 filtermap:在需要同時取得位置與值時,可先使用 map 產生索引陣列,再配合 filter 篩選。
  4. 利用 Set 取代頻繁搜尋const set = new Set(arr); set.has(value); 在大量搜尋時效能更佳。

實際應用場景

1. 表單驗證 – 防止重複提交

在使用者點擊「送出」按鈕時,常需要檢查已提交的項目是否已存在於暫存陣列中:

let submittedIds = [101, 203, 304];

function canSubmit(id) {
  // 使用 includes 判斷是否已提交
  return !submittedIds.includes(id);
}

// 範例
if (canSubmit(203)) {
  // 送出
} else {
  console.warn('此項目已提交過!');
}

2. 文字搜尋 – 高亮顯示關鍵字

在一段文字中找出所有關鍵字的出現位置,最後一次出現的位置常用於決定捲動位置:

const paragraph = 'JavaScript 是一門靈活的程式語言,JavaScript 也被廣泛應用於前端。';
const keyword = 'JavaScript';

const firstIdx = paragraph.indexOf(keyword);
const lastIdx  = paragraph.lastIndexOf(keyword);

console.log(`第一個出現在 ${firstIdx},最後一個出現在 ${lastIdx}`);

3. 去除陣列重複元素(保留最後一次出現)

有時候需要保留每個值最後一次出現的順序,可結合 lastIndexOf

function uniqKeepLast(arr) {
  return arr.filter((item, idx) => arr.lastIndexOf(item) === idx);
}

const data = [1, 2, 3, 2, 4, 1];
console.log(uniqKeepLast(data)); // [3, 2, 4, 1]

4. 互動式選單 – 高亮最近點選的項目

在多選清單中,使用者點選過的項目需要被「標記」:

let history = []; // 紀錄點選順序

function select(item) {
  if (!history.includes(item)) {
    history.push(item);
  }
  // 高亮最近一次點選的項目
  const lastIdx = history.lastIndexOf(item);
  console.log(`項目 ${item} 最近一次出現在索引 ${lastIdx}`);
}

總結

includesindexOflastIndexOfJavaScript 陣列搜尋 的三大基礎工具。

  • includes布林 回傳是否存在,語意最清晰,且能正確偵測 NaN
  • indexOf 取得 第一個匹配 的索引,適合需要定位元素的位置。
  • lastIndexOf 取得 最後一個匹配 的索引,常用於去重或找出最近的出現點。

在實務開發中,依照需求選擇最合適的方法,並留意 相等性、NaNfromIndex 等細節,可避免常見錯誤、提升程式可讀性與效能。結合 SetMap 或自訂函式,甚至利用這三個方法的特性實作更複雜的演算法,都是提升 JavaScript 技能的好方法。希望本篇文章能幫助你在陣列操作上更加得心應手,寫出更乾淨、可靠的程式碼!