indexOf は文字列や配列の中から指定した値が最初に見つかった位置(インデックス)を返すメソッドです。見つからなかった場合は -1 を返します。文字列の解析、配列の要素検索、slice との組み合わせによる部分文字列の抽出など、実務で使う場面が非常に多いメソッドです。
・文字列の indexOf の基本構文と戻り値
・検索開始位置(第 2 引数)の指定方法
・見つからない場合の -1 判定パターン
・lastIndexOf で末尾から検索する方法
・配列の indexOf の基本と注意点
・大文字・小文字を無視して検索する方法
・全出現位置を配列で取得する方法
・includes との使い分け
文字列の indexOf の基本
const index = str.indexOf(searchString, fromIndex); // searchString: 検索する文字列 // fromIndex: 検索開始位置(省略可、デフォルト 0) // 戻り値: 最初に見つかった位置(0 始まり)、見つからなければ -1
const str = "JavaScript is awesome";
console.log(str.indexOf("Script")); // 4
console.log(str.indexOf("is")); // 11
console.log(str.indexOf("Python")); // -1(見つからない)
console.log(str.indexOf("a")); // 1(最初の "a" の位置)
検索開始位置を指定する
第 2 引数 fromIndex を指定すると、その位置以降から検索を開始します。同じ文字列の 2 番目以降の出現位置を探すときに使います。
const str = "abcabc";
console.log(str.indexOf("abc")); // 0(最初の出現)
console.log(str.indexOf("abc", 1)); // 3(1番目以降で次の出現)
console.log(str.indexOf("abc", 4)); // -1(4番目以降には見つからない)
空文字列を検索した場合
const str = "Hello";
// 空文字列は常に見つかる
console.log(str.indexOf("")); // 0
console.log(str.indexOf("", 3)); // 3(fromIndex がそのまま返る)
console.log(str.indexOf("", 10)); // 5(文字列の長さが上限)
見つからない場合の -1 判定
indexOf の戻り値で最も重要なのは -1(見つからない)の判定です。
const url = "https://example.com/search?q=javascript";
// 含まれているかの判定
if (url.indexOf("?") !== -1) {
console.log("クエリパラメータあり");
}
// 含まれていない場合の判定
if (url.indexOf("#") === -1) {
console.log("ハッシュなし");
}
indexOf はインデックス 0 で見つかると 0(falsy)を返します。if (str.indexOf("x")) と書くと、0 番目で見つかった場合に false 扱いになるバグの原因になります。必ず === -1 または !== -1 で比較してください。const str = "abc";
// NG: indexOf が 0 を返すと false 扱いになる
if (str.indexOf("a")) {
console.log("見つかった"); // 実行されない!
}
// OK: -1 と比較する
if (str.indexOf("a") !== -1) {
console.log("見つかった"); // 正しく実行される
}
lastIndexOf で末尾から検索する
lastIndexOf は文字列(または配列)の末尾側から検索し、最後に見つかった位置を返します。戻り値のインデックスは先頭から数えた値です。
const path = "/home/user/documents/file.txt";
// 最後の "/" の位置
console.log(path.lastIndexOf("/")); // 20
// 最後の "." の位置(拡張子の区切り)
console.log(path.lastIndexOf(".")); // 30
// indexOf と比較
console.log(path.indexOf("/")); // 0(最初の "/")
console.log(path.lastIndexOf("/")); // 20(最後の "/")
const filepath = "/images/photo-2026.jpg";
// ファイル名(最後の / 以降、拡張子なし)
const slashPos = filepath.lastIndexOf("/");
const dotPos = filepath.lastIndexOf(".");
const filename = filepath.slice(slashPos + 1, dotPos);
console.log(filename); // "photo-2026"
// 拡張子
const ext = filepath.slice(dotPos);
console.log(ext); // ".jpg"
配列の indexOf
配列にも同名の indexOf メソッドがあり、指定した値が最初に見つかったインデックスを返します。
const colors = ["red", "green", "blue", "green"];
console.log(colors.indexOf("green")); // 1(最初の出現)
console.log(colors.indexOf("yellow")); // -1(見つからない)
// 検索開始位置を指定
console.log(colors.indexOf("green", 2)); // 3(2番目以降の出現)
オブジェクト配列では使えない
配列の indexOf は厳密等価(===)で比較するため、同じ内容でも別のオブジェクトインスタンスでは見つかりません。
const users = [{ id: 1 }, { id: 2 }];
// 別のオブジェクト → 見つからない
console.log(users.indexOf({ id: 1 })); // -1
// 同じ参照なら見つかる
const target = users[0];
console.log(users.indexOf(target)); // 0
// オブジェクトの内容で検索するなら findIndex を使う
console.log(users.findIndex(u => u.id === 1)); // 0
NaN は見つけられない
const arr = [1, NaN, 3]; console.log(arr.indexOf(NaN)); // -1(見つけられない) console.log(arr.includes(NaN)); // true(includes は見つけられる)
includes、オブジェクトの内容で検索するなら findIndex を使いましょう。大文字・小文字を無視して検索する
indexOf は大文字・小文字を区別します。区別せずに検索したい場合は、両方を小文字に変換してから検索します。
function indexOfIgnoreCase(str, search) {
return str.toLowerCase().indexOf(search.toLowerCase());
}
const text = "Hello JavaScript World";
console.log(indexOfIgnoreCase(text, "javascript")); // 6
console.log(indexOfIgnoreCase(text, "HELLO")); // 0
全出現位置を配列で取得する
indexOf を繰り返し呼び出すことで、文字列中のすべての出現位置を配列として取得できます。
function findAllIndexes(str, search) {
const positions = [];
let pos = -1;
while ((pos = str.indexOf(search, pos + 1)) !== -1) {
positions.push(pos);
}
return positions;
}
console.log(findAllIndexes("abcabcabc", "abc")); // [0, 3, 6]
console.log(findAllIndexes("banana", "an")); // [1, 3]
const str = "abcabcabc"; const positions = [...str.matchAll(/abc/g)].map(m => m.index); console.log(positions); // [0, 3, 6]
indexOf と includes の使い分け
| 比較項目 | indexOf | includes |
|---|---|---|
| 戻り値 | インデックス(見つからなければ -1) | true / false |
| NaN の判定 | 見つけられない | 見つけられる |
| 位置の取得 | できる | できない |
| 可読性 | !== -1 が冗長 |
直感的 |
| IE 対応 | IE 対応 | IE 非対応 |
const str = "Hello World";
// 「含まれているか」だけを知りたい → includes
if (str.includes("World")) { /* ... */ }
// 「どこにあるか」を知りたい → indexOf
const pos = str.indexOf("World");
if (pos !== -1) {
const before = str.slice(0, pos);
console.log(before); // "Hello "
}
includes、位置が必要なら indexOf。この使い分けを徹底するとコードの可読性が上がります。実務でよく使うパターン
URL からクエリパラメータ部分を抽出する
function getQueryString(url) {
const qPos = url.indexOf("?");
if (qPos === -1) return "";
return url.slice(qPos + 1);
}
console.log(getQueryString("https://example.com/search?q=js&lang=ja"));
// "q=js&lang=ja"
メールアドレスからユーザー名とドメインを分離する
function splitEmail(email) {
const atPos = email.indexOf("@");
if (atPos === -1) return null;
return {
user: email.slice(0, atPos),
domain: email.slice(atPos + 1)
};
}
console.log(splitEmail("tanaka@example.com"));
// { user: "tanaka", domain: "example.com" }
特定のキーワードをハイライトする
function highlight(text, keyword) {
const lowerText = text.toLowerCase();
const lowerKey = keyword.toLowerCase();
const pos = lowerText.indexOf(lowerKey);
if (pos === -1) return text;
const before = text.slice(0, pos);
const match = text.slice(pos, pos + keyword.length);
const after = text.slice(pos + keyword.length);
return `${before}<mark>${match}</mark>${after}`;
}
console.log(highlight("JavaScript is great", "script"));
// "Java<mark>Script</mark> is great"
関連記事
- includes の使い方 — 配列・文字列の存在チェック
- slice の使い方 — 文字列・配列の切り出し
- substring の使い方 — indexOf との組み合わせ
- replace で文字列を置換する方法
- match で文字列パターンを検索する方法
- 文字列内の特定文字の出現回数をカウントする方法
よくある質問
slice や substring に渡すと、-1 が末尾からの位置として解釈されたり 0 に変換されたりして、意図しない結果になります。indexOf の戻り値は必ず === -1 でチェックしてから使いましょう。indexOf は先頭から検索して最初の出現位置を返し、lastIndexOf は末尾から検索して最後の出現位置を返します。ファイルパスの拡張子取得(最後の .)やディレクトリ取得(最後の /)には lastIndexOf が適しています。str.search(/pattern/) を使います。ただし search は検索開始位置を指定できないため、全出現位置の取得には matchAll が適しています。indexOf(value) は値の一致で検索し、findIndex(fn) はコールバック関数の条件で検索します。プリミティブ値の配列には indexOf、オブジェクト配列やカスタム条件には findIndex を使い分けます。str.toLowerCase().indexOf(search.toLowerCase()) のように両方を小文字に変換してから検索します。まとめ
indexOf は文字列と配列の両方で使える位置検索メソッドです。
- 基本: 最初に見つかった位置を返す。見つからなければ
-1 - lastIndexOf: 末尾から検索して最後の出現位置を返す
- -1 判定:
!== -1で必ず比較する(0 が falsy になるバグ防止) - 配列の注意点: オブジェクトは参照比較、NaN は見つけられない
- includes との使い分け: 存在チェックだけなら includes、位置が必要なら indexOf
slice や substring との組み合わせで文字列の解析(URL解析・メール分割・拡張子取得)に威力を発揮します。戻り値の -1 チェックを忘れないことが、indexOf を安全に使うための最重要ポイントです。