在 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 | 搜尋 undefined 或 null 需完全匹配 |
| 常用場景 | 檢查文字關鍵字 | 檢查清單中是否存在某個值 |
使用情境
判斷是否包含
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); // 回傳 1lastIndexOf(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));
// ➜ 過濾出所有只出現一次的值