web-dev-qa-db-ja.com

Array.prototype.includesとArray.prototype.indexOf

読みやすさの改善以外に、includesに比べてindexOfには利点がありますか?彼らは私と同じように見えます。

これの違いは何ですか

var x = [1,2,3].indexOf(1) > -1; //true

この?

var y = [1,2,3].includes(1); //true
90
Matt

tl; dr:NaNは別の方法で処理されます。

  • [NaN].indexOf(NaN) > -1falseです
  • [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パラメーターを追加します。


さらに詳しい情報:

119
Felix Kling

パフォーマンスについては、現時点ではindexOfの方が高速ですが、この JSperf テストでは、時間が経過するほどincludes()indexOf(さらに最適化する)。

私見、if (arr.includes(el)) {}よりも明確で保守性が高いので、if (arr.indexOf(el) !== -1) {}を書くことも好みます

9
538ROMEO

.indexOf()および.includes()メソッドを使用して、配列内の要素を検索したり、特定の文字列内の文字/部分文字列を検索したりできます。

配列での使用

リンク ECMAScript仕様へ)

  1. indexOfStrict Equality Comparison を使用しますが、includesSameValueZero アルゴリズムを使用します。このため、次の2つの相違点が生じます。

  2. Felix Kling で指摘されているように、NaNの場合の動作は異なります。

let arr = [NaN];

arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
  1. undefinedの場合の動作も異なります。
let arr = [ , , ];

arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true

文字列での使用

リンク ECMAScript仕様へ)

  1. RegExpを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 指摘したように、includesindexOfよりも少し(非常に小さい)遅いかもしれません(最初の引数として正規表現をチェックする必要があるため) 、これは大きな違いをもたらさず、ごくわずかです。

歴史

String.prototype.includes()はECMAScript 2015で導入されましたが、Array.prototype.includes()はECMAScript 2016で導入されました。ブラウザのサポートに関しては、賢明に使用してください。

String.prototype.indexOf()およびArray.prototype.indexOf()はECMAScriptのES5エディションに存在するため、すべてのブラウザーでサポートされています。

2
Srishti

概念的には、位置indexOfを使用する場合は、indexOfを使用する必要があります。値の抽出または配列の操作、つまり、要素の位置を取得した後のスライス、シフト、または分割を使用します。一方、Array.includesを使用するのは、値が配列の内側にあるかどうかを知るためだけであり、位置は気にしないためです。

1
Sebastian Gomez