includes() と indexOf() の使い分け、-1 が返る理由と 0 が falsy になる落とし穴、大文字小文字を無視した検索、split() と join() での分解と組み立てを実行して確かめます。
「この文字が入っているか」を知りたいだけなら includes() です。真偽値が返ります。
example.js
const title = 'プログラミング大全';
console.log(title.includes('大全'));
console.log(title.includes('入門'));
出力書き換えて実行できます
true
false
example.js
const title = 'プログラミング大全';
console.log(title.indexOf('大全'));
console.log(title.indexOf('プロ'));
出力書き換えて実行できます
7
0
if にそのまま書けるので、あるか無いかだけ知りたいときはこれが最短です。
位置まで知りたいときは indexOf()
見つかった添字を返します。
example.js
console.log('プログラミング大全'.indexOf('入門'));
出力書き換えて実行できます
-1
javascript
const title = 'プログラミング大全';
if (title.indexOf('プロ')) {
console.log('見つかった');
} else {
console.log('見つからなかった');
}
見つからなかった
無いときは-1を返します。
example.js
const title = 'プログラミング大全';
if (title.indexOf('プロ') !== -1) {
console.log('見つかった');
}
出力書き換えて実行できます
見つかった
example.js
const file = 'report-2026.pdf';
console.log(file.startsWith('report'));
console.log(file.endsWith('.pdf'));
console.log(file.lastIndexOf('-'));
出力書き換えて実行できます
true
true
6
なぜ -1 なのか。 添字は0から始まるので、0 は「先頭で見つかった」という正しい答えです。
「無い」を表すには、添字としてありえない値が要ります。それが -1 です。
ここが落とし穴
indexOf() の結果を、そのまま if に書いてはいけません。
example.js
const word = 'JavaScript';
console.log(word.includes('script'));
console.log(word.includes('Script'));
出力書き換えて実行できます
false
true
example.js
const word = 'JavaScript';
const keyword = 'SCRIPT';
console.log(word.toLowerCase().includes(keyword.toLowerCase()));
出力書き換えて実行できます
true
先頭にあるのに、無いと判定されました。
indexOf('プロ') は 0 を返し、0 はfalsy(偽として扱われる値)だからです。
書くなら比較を省かないでください。
example.js
const word = 'Straße';
console.log(word.length);
console.log(word.toUpperCase());
console.log(word.toUpperCase().length);
出力書き換えて実行できます
6
STRASSE
7
example.js
console.log('2026-09-08'.split('-'));
console.log('りんご,みかん,ぶどう'.split(','));
出力書き換えて実行できます
[ '2026', '09', '08' ]
[ 'りんご', 'みかん', 'ぶどう' ]
あるか無いかだけなら includes() を使えば、この間違いは起きません。
indexOf() は位置が要るときだけ使ってください。
先頭・末尾だけ調べる
example.js
console.log('見つからない'.split(','));
出力書き換えて実行できます
[ '見つからない' ]
example.js
console.log('a,,b'.split(','));
出力書き換えて実行できます
[ 'a', '', 'b' ]
lastIndexOf() は後ろから探して、最後に見つかった位置を返します。
拡張子やディレクトリの区切りを探すときに使います。
大文字と小文字を区別する
検索は1文字ずつそのまま比べます。大文字と小文字は別の文字です。
example.js
const input = ' りんご , みかん , ぶどう ';
console.log(input.split(',').map((item) => item.trim()));
出力書き換えて実行できます
[ 'りんご', 'みかん', 'ぶどう' ]
example.js
const fruits = ['りんご', 'みかん', 'ぶどう'];
console.log(fruits.join(' / '));
console.log(fruits.join(''));
console.log([2026, 9, 8].join('-'));
出力書き換えて実行できます
りんご / みかん / ぶどう
りんごみかんぶどう
2026-9-8
無視したいときは、両方を同じ側に揃えてから比べます。
example.js
const path = 'a-b-c';
console.log(path.replace('-', '+'));
console.log(path.replaceAll('-', '+'));
出力書き換えて実行できます
a+b-c
a+b+c
example.js
console.log('価格'.replace('価格', '$&円'));
出力書き換えて実行できます
価格円
片方だけ変換すると、もう片方が大文字のときに外れます。必ず両方を揃えてください。
大文字にすると長さが変わることがある
ドイツ語の ß は、大文字にすると SS の2文字になります。
文字数が変わらない前提でコードを書かないでください。
半角カタカナのように、大文字小文字の区別が無くて何も変わらない文字もあります。
区切って配列にする
split() は区切り文字で分けて配列にします。
見つからないときも空にはなりません。元の文字列が1つだけ入った配列が返ります。
区切りが続いていると、間に空文字列が入ります。
これは不具合ではありません。 「区切りが2つあるので、間に空の項目がある」という素直な結果です。
→ split() の詳しい挙動
分けたあとに整える
入力を分けると、たいてい前後に空白が残ります。第2回の trim() と組み合わせます。
つなぎ直す
join() は配列を1つの文字列にします。split() の逆です。
数値の配列でも、自動で文字列に変えてつなぎます。
置き換える
replace() は最初の1つしか置き換えません。
全部を置き換えたいなら replaceAll() です。
replace() の挙動は忘れやすいので、意図が「全部」なら名前で示してください。
置き換える文字列の中で $ は特別扱いされます。
$& が「見つかった文字列そのもの」に置き換わっています。
金額を扱うコードで思わぬ結果になります。
→ replace() の詳しい挙動
まとめ
- あるか無いかだけなら
includes()。真偽値が返る
- 位置が要るときだけ
indexOf()。無いときは-1
if (s.indexOf(x)) は間違い。 0 がfalsyなので先頭を見落とす
- 大文字小文字を無視するなら両方を揃える。
ß のように長さが変わる文字がある
split() は見つからなくても空にならない。1つ入った配列が返る
replace() は最初の1つだけ。全部なら replaceAll()
次に学ぶ
ここまで「1文字」という言葉を、深く考えずに使ってきました。
ですが length は、見た目の文字数と一致しないことがあります。
絵文字や結合文字で何が起きるのか、正しく数えるにはどうするかを学びます。
→ 第4回: 文字を正しく数える