読みやすさの改善以外に、includes
に比べてindexOf
には利点がありますか?彼らは私と同じように見えます。
これの違いは何ですか
var x = [1,2,3].indexOf(1) > -1; //true
この?
var y = [1,2,3].includes(1); //true
tl; dr:NaN
は別の方法で処理されます。
[NaN].indexOf(NaN) > -1
はfalse
です[NaN].includes(NaN)
はtrue
です提案 から:
動機
ECMAScript配列を使用する場合、配列に要素が含まれているかどうかを確認することが一般に望まれます。このための一般的なパターンは
if (arr.indexOf(el) !== -1) { ... }
他のさまざまな可能性、例えば
arr.indexOf(el) >= 0
、または~arr.indexOf(el)
。これらのパターンには2つの問題があります。
- 彼らは「あなたの言っていることを言う」ことに失敗します:配列に要素が含まれているかどうかを尋ねる代わりに、配列内のその要素の最初の出現のインデックスを尋ね、次にそれを比較するかビットをいじって決定します実際の質問に対する答え。
NaN
は厳密な等価比較を使用し、したがって[NaN].indexOf(NaN) === -1
を使用するため、indexOf
に対して失敗します。提案されたソリューション
上記のパターンを次のように書き換えられるように、
Array.prototype.includes
メソッドの追加を提案しますif (arr.includes(el)) { ... }
これは上記とほぼ同じセマンティクスを持ちますが、厳密な等価比較の代わりにSameValueZero比較アルゴリズムを使用するため、
[NaN].includes(NaN)
がtrueになります。したがって、この提案は既存のコードに見られる両方の問題を解決します。
一貫性を保つために、
Array.prototype.indexOf
およびString.prototype.includes
に似たfromIndex
パラメーターを追加します。
さらに詳しい情報:
パフォーマンスについては、現時点ではindexOfの方が高速ですが、この JSperf テストでは、時間が経過するほどincludes()
がindexOf
(さらに最適化する)。
私見、if (arr.includes(el)) {}
よりも明確で保守性が高いので、if (arr.indexOf(el) !== -1) {}
を書くことも好みます
.indexOf()
および.includes()
メソッドを使用して、配列内の要素を検索したり、特定の文字列内の文字/部分文字列を検索したりできます。
( リンク ECMAScript仕様へ)
indexOf
は Strict Equality Comparison を使用しますが、includes
は SameValueZero アルゴリズムを使用します。このため、次の2つの相違点が生じます。
Felix Kling で指摘されているように、NaN
の場合の動作は異なります。
let arr = [NaN];
arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
undefined
の場合の動作も異なります。let arr = [ , , ];
arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true
( リンク ECMAScript仕様へ)
indexOf
に渡すと、RegExpを文字列として扱い、見つかった場合は文字列のインデックスを返します。ただし、includes
にRegExpを渡すと、例外がスローされます。let str = "javascript";
str.indexOf(/\w/); // returns -1 even though the elements match the regex because /\w/ is treated as string
str.includes(/\w/); // throws TypeError: First argument to String.prototype.includes must not be a regular expression
538ROMEO 指摘したように、includes
はindexOf
よりも少し(非常に小さい)遅いかもしれません(最初の引数として正規表現をチェックする必要があるため) 、これは大きな違いをもたらさず、ごくわずかです。
String.prototype.includes()
はECMAScript 2015で導入されましたが、Array.prototype.includes()
はECMAScript 2016で導入されました。ブラウザのサポートに関しては、賢明に使用してください。
String.prototype.indexOf()
およびArray.prototype.indexOf()
はECMAScriptのES5エディションに存在するため、すべてのブラウザーでサポートされています。
概念的には、位置indexOfを使用する場合は、indexOfを使用する必要があります。値の抽出または配列の操作、つまり、要素の位置を取得した後のスライス、シフト、または分割を使用します。一方、Array.includesを使用するのは、値が配列の内側にあるかどうかを知るためだけであり、位置は気にしないためです。