Array.prototype.includesとArray.prototype.indexOf


112

読みやすさが向上しただけでなく、それincludes以上の利点はありますindexOfか?彼らは私と同じように見えます。

これの違いは何ですか

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

この?

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

12
includesブラウザのサポートがはるかに悪い。
クエンティン

4
includesはES6 / ES2015の一部ではないことに注意してください。ECMAScriptの次のバージョンの提案であり、今年追加される予定です。
Felix Kling 2016

4
includesIEでまったくサポートされていないことについても言及したいと
思い

回答:


138

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、これらは失敗します。indexOf[NaN].indexOf(NaN) === -1

提案されたソリューション

Array.prototype.includes上記のパターンを次のように書き換えられるように、メソッドの追加を提案します。

if (arr.includes(el)) {
    ...
}

これは、厳密な等価比較の代わりにSameValueZero比較アルゴリズムを使用することを除いて、上記とほぼ同じセマンティクスを持ち、真になり[NaN].includes(NaN)ます。

したがって、この提案は、既存のコードに見られる両方の問題を解決します。

さらに、一貫性を保つためfromIndexArray.prototype.indexOf、およびと同様のパラメーターを追加しますString.prototype.includes


さらに詳しい情報:


1
真実の半分だけ。また異なります:不足している要素はundefinedによって扱われ、によって.includes()考慮されません.indexOf()
Robert Siemer

11

パフォーマンスについて疑問がある場合、当面はindexOfの方が高速ですが、このJSperfテストでは、時間が経過includes()するほど高速indexOfになることが示されています(さらに最適化されると思います)。

私見、私if (arr.includes(el)) {}は書くことを好むif (arr.indexOf(el) !== -1) {}


1
パフォーマンスの違いはそれほど明白ではないようです。私のモバイルFirefoxは、indexOfが実際に高速であることを示しています。一部のChromeバージョンは同じように動作します...しかし、今日の実装では、違いはとにかく無視できるようです。
Nux 2018

8

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

配列での使用

(ECMAScript仕様へのリンク

  1. indexOf使用して厳密な等価比較のに対し、includes用途SameValueZeroアルゴリズムを。このため、次の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 は文字列として扱われ、見つかった場合は文字列のインデックスが返されます。ただし、RegExpをincludesに渡すと、例外がスローされます。
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与えtrue明示的に設定した後undefined:配列にlet arr=[undefined];またはlet arr=[];arr[0]=undefined;arr.indexOf(undefined) === 0
ジェイDadhania

あなただけがとの違いを示していますundefined:理由は、.includes欠落している要素をとして扱いundefined.indexOf()それらを無視するためです。を使用して、不足している要素を「作成」することもできますarr[number beyond length] = whatever
Robert Siemer

誰も文字列を求めていませんでしたが、あなたの意見は、.includes()文字列のみを食べることを示唆しています。実際には、どちらの方法でも、できる限り文字列に強制的に変換します。Regexは、現在のドラフトに従って標準将来追加すること.includes()許可するための引数として明確に除外されています。
Robert Siemer

4

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


0

indexOf()また、includes()どちらも配列内の要素を見つけるために使用できますが、各関数は異なる戻り値を生成します。

indexOf数値を返します(-1要素が配列に存在しない場合、または要素が存在する場合は配列の位置)。

includes()ブール値(trueまたはfalse)を返します。


こんにちはクルティ、この質問はすでに回答されており、承認された回答があります。さらに、他の回答ですでに述べられている情報のみが回答に含まれていることを確認できます。結局のところ、質問はすでに4歳です。最新の質問または未回答の質問についてのガイダンスを提供してください。ありがとう
leonardfactory
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.