indexOf() 協尋高手

在 JavaScript 中,indexOf() 是一個非常實用的方法,用在尋找特定元素或子字串在陣列/字串中第一次出現的位置索引(Index)。

除了用於判斷字串或陣列是否包含某個子字串 / 元素之外,也用於切割字串或是安全判斷,以下筆記一下 indexOf() 的基本觀念與使用方法。

核心觀念

  • 回傳值:如果有找到指定的元素找到了,就回傳該元素的 索引值(從 0 開始);如果找不到,則回傳 –1
  • 比對方式indexOf()使用「嚴格相等」進行比較(即 ===),這意味著型別必須完全一致。

用於字串 (String.prototype.indexOf)

基本語法(字串)
string.indexOf(searchValue, fromIndex?)
  • searchValue:你要找的字串
  • fromIndex(可選):從第幾個位置開始找

在字串中,它用於尋找特定字元的起始位置。

"hello".indexOf("e")// 1<br>"hello".indexOf("l")// 2(第一個 l)
// 為什麼是 2?
// `h(0) e(1) l(2) l(3) o(4)`

"hello".indexOf("z")// -1
注意事項
  • 區分大小寫indexOf("H") 會回傳 -1,因為字串中是大寫的 “hello”。
  • 第二個參數:你可以傳入一個起始位置,告訴程式從哪裡開始找。
const str = "apple, banana, apple";
console.log(str.indexOf("apple", 5)); // 回傳 15 (跳過第一個 apple,從索引 5 開

用於陣列 (Array.prototype.indexOf)

在陣列中,它用於尋找某個元素在陣列中的索引。

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

console.log(fruits.indexOf("orange")); // 回傳 2
console.log(fruits.indexOf("apple"));  // 回傳 0 (只會找第一個出現的)
console.log(fruits.indexOf("grape"));  // 回傳 -1
注意事項:嚴格相等 (Strict Equality)

要注意的是 indexOf() 使用 === 比較,這在處理物件或陣列時容易出錯:

const arr = [{ name: "Alice" }];
console.log(arr.indexOf({ name: "Alice" })); // 回傳 -1
// 因為在記憶體中,這兩個物件的參考位置不同,被判定為不相等。

陣列與字串的差異比較

特性字串 (String)陣列 (Array)
尋找目標子字串 (可以是多個字元)單一元素 (Element)
找不到時回傳 -1回傳 -1
空值處理indexOf("") 通常回傳 0搜尋 undefinednull 需完全匹配
常用場景檢查文字關鍵字檢查清單中是否存在某個值

使用情境

判斷是否包含
if (str.indexOf("abc") !== -1) {}

// 有包含
切割字串
const email ="test@gmail.com";
const at = email.indexOf("@");

email.slice(0, at);// "test"
安全判斷(避免錯誤)
const idx = str.indexOf("T");
if (idx !== -1) {str = str.slice(0, idx);}
小陷阱

錯誤寫法

if (str.indexOf("a")) {}

// 可能永遠不會有條件符合,進入 {}區塊

為什麼?如果 a 在第 0 個位置:

"a123".indexOf("a")// 0 → false

正確寫法

if (str.indexOf("a") !== -1) {
}
// 或這樣寫
if (str.includes("a")) {
}

實戰情境-1

假設後端給你的是 ISO 日期:

const value ="2026-01-01T00:00:00";

const idx = value.indexOf("T");

字串實際長這樣:

0         1
0123456789012345678
2026-01-01T00:00:00
index = 10
value.indexOf("T");// 10

搭配判斷式


const value = "2026-01-01T00:00:00";
const idx = value.indexOf("T");

const dateOnly =  idx === -1 ? value : value.slice(0, idx);
// "2026-01-01"

等於:

  • T → 切掉時間
  • T → 原樣回傳

為什麼不用 includes()?

你可能會想:

value.includes("T")

includes() 可以知道是否有包含 ”T”,但無法知道 “T” 的位置:

方法能不能知道位置能不能切字串
indexOf✅ 可以✅ 可以
includes❌ 只能 true / false❌ 不行

因為你接著要用 slice(), 你需要的是「位置」

value.slice(0, idx)

實戰情境-判斷陣列唯一值

indexOf() 可以用來判斷某個值 i 在陣列中是否只出現一次

arr.indexOf(i) === arr.lastIndexOf(i)

indexOf(value)

  • 功能:回傳「第一次」出現 value 的索引(index)
  • 找不到時:會回傳 -1
const arr = [1, 2, 2, 3];
arr.indexOf(2); // 回傳 1

lastIndexOf(value)

  • 功能:回傳「最後一次」出現 value 的索引
  • 找不到時:一樣回傳 -1
const arr = [1, 2, 2, 3];
arr.lastIndexOf(2); // 回傳 2

結合使用

arr.indexOf(i) === arr.lastIndexOf(i)

這句話的意思是:「這個值 i 在陣列中第一次出現的位置和最後一次出現的位置相同」,代表這個值只出現一次!

範例比較

const arr = [1, 2, 2, 3, 4, 4, 5];

arr.indexOf(2); // 1
arr.lastIndexOf(2); // 2 (「不同」代表 出現過兩次)

arr.indexOf(3); // 3
arr.lastIndexOf(3); // 3 (「相同」代表 只出現一次)

如果要找出只有出現過一次的元素

arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// ➜ 過濾出所有只出現一次的值