DESIGN / CODE / INFRA / AI

解説

NaNがあるのにindexOfは-1?includesとの比較ルールを確かめよう

数値・文字列・NaNを含む配列で、存在確認と位置検索の違いを比較。0を偽として扱う分岐の落とし穴も作例で確認。

NaNがあるのにindexOfは-1?includesとの比較ルールを確かめよう
保存リストを見る →
この記事の道しるべ 4項目

配列に値があるか調べたいだけなのに、indexOfの結果で判定すると見つからない。特にNaNや先頭の値を扱うときは、比較のルールと返り値を分けて確認しよう。

このページは、配列とifの基本が分かる人向け。固定の値だけを使うブラウザ作例で、includesとindexOfが何を返すかを試すよ。

返すものがまず違う

const values = [10, NaN, '10'];
values.includes(10); // true
values.indexOf(10);  // 0

includesは含まれるかどうかをtrue・falseで返す。indexOfは最初に見つかった位置を0から数えた数字で返し、見つからなければ-1を返すよ。

「存在するか」だけならincludes、「最初の位置も必要」ならindexOfが候補になる。名前の違いだけで選ぶより、次の処理で何が必要かを先に決めたいね。

NaNでは比較の結果が違う

NaNは、数として表せない計算結果などを表す特別な数値。文字列の"NaN"とは別の値だよ。

values.includes(NaN); // true
values.indexOf(NaN);  // -1

includesはSameValueZeroという比較を使い、この比較ではNaN同士を同じと扱う。indexOfは厳密な等価性に基づく比較を使うため、NaNを見つけられない。これが、同じ配列でも結果が変わる理由なんだ。

どちらも数値10と文字列'10'を自動で同じ値へ変換しない。作例で数値10、文字列10、NaN、存在しない20を切り替え、true・falseと位置の違いを見てみよう。

探す値 includes indexOf
数値10 true 0
NaN true -1
文字列'10' true 2
数値20 false -1

indexOfをそのままifへ入れない

if (values.indexOf(10)) {
  // 先頭の0は偽なので、ここへ入らない
}

さらに、見つからないときの-1は真として扱われる。存在確認としてそのまま条件へ使うと、意図と逆の判断になり得るよ。

位置を使うなら、返り値が-1ではないことを明示して調べる。存在だけならincludesの真偽値を使えば、位置と真偽の変換を混ぜずに済む。

const found = values.indexOf(10) !== -1;

この例の!== -1も、indexOfでNaNを見つけられるようにする処置ではない。比較方法の違いは残るので、対象の値に合わせて選んでね。

作例を戻しながら比べる

選択欄で四つの値を切り替えると、二つの結果とindexOfを真偽値に変換した結果が出る。「最初から試す」で数値10へ戻せるよ。NaNをJSONだけで表示するとnullへ変わることがあるため、作例は型付きの説明も併記している。

2026年10月29日にMDNの比較方法を確認し、四つのケースをNodeとブラウザで検証した。findとfilter、Setの値と参照も、必要な返り値を選ぶ練習になるよ。

動かしてみよう:includes / indexOf

設定を切り替え、実際の表示と結果を比べよう。「最初から試す」で初期状態へ戻せるよ。

参考・出典

公開と変更の記録
  • :初回公開

日時は日本時間です。記載のある変更は、確認できた編集記録に基づきます。更新日の違いだけから変更内容を推測して載せることはありません。

更新・訂正の方針 →

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。