Code Fix

上級

indexOf(NaN)が常に-1を返し、NaNを見つけられない理由

Array.prototype.indexOfは===(厳密等価)で要素を探すため、自分自身とも等しくないNaNを絶対に見つけられません。includes()はSameValueZeroというNaNを特別扱いするアルゴリズムを使うため、NaNも正しく検出できます。

なぜエラーが出ないのか

出力: -1
(エラーなし)
JavaScriptは何も報告しません。文法として正しいためです
出力: -1
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  const values = [1, NaN, 3];
 2  console.log(values.indexOf    (NaN));
                            ^
出力: -1期待: true (エラーにはなりません)

indexOfは===で比較するため、自分自身とも等しくないNaNを絶対に見つけられません。includes()はNaNを特別扱いするSameValueZeroで比較するため正しく検出できます。

直し方: indexOfincludes にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  const readings = [12, NaN, 8];
 2  console.log(readings.indexOf    (NaN));
                              ^
出力: -1期待: true (エラーにはなりません)

配列の途中にあってもindexOfはNaNを見つけられません。includes()を使う必要があります。

直し方: indexOfincludes にします。

この問題を解いてみる →

パターン3

 1  const samples = [NaN, 5, 9];
 2  console.log(samples.indexOf    (NaN));
                             ^
出力: -1期待: true (エラーにはなりません)

配列の先頭であってもindexOfはNaNを見つけられません。includes()を使う必要があります。

直し方: indexOfincludes にします。

この問題を解いてみる →

よくある誤解

「配列に含まれているかを調べるならindexOfでもincludesでも同じはず」という思い込みは、NaNが絡む場面では成り立ちません。NaNの検出だけはincludesでなければ正しく動きません。

まとめ

indexOf(NaN)が常に-1を返し、NaNを見つけられない理由は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)