web-dev-qa-db-fra.com

Array.prototype.includes vs. Array.prototype.indexOf

Au-delà de la lisibilité améliorée, y a-t-il un avantage à includes par rapport à indexOf? Ils semblent identiques à moi.

Quelle est la difference entre this

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

Et ça?

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

tl; dr: NaN est traité différemment:

  • [NaN].indexOf(NaN) > -1 est false
  • [NaN].includes(NaN) est true

De la proposition :

Motivation

Lors de l'utilisation de tableaux ECMAScript, il est généralement souhaitable de déterminer si le tableau comprend un élément. Le modèle dominant pour ceci est

if (arr.indexOf(el) !== -1) {
    ...
}

avec diverses autres possibilités, par exemple arr.indexOf(el) >= 0, ou même ~arr.indexOf(el).

Ces modèles présentent deux problèmes:

  • Ils ne parviennent pas à "dire ce que vous voulez dire": au lieu de demander si le tableau comprend un élément, vous demandez quel est l'indice de la première occurrence de cet élément dans le tableau, puis vous le comparez ou le bousculez pour déterminer la réponse à votre question réelle.
  • Ils échouent pour NaN, car indexOf utilise la comparaison d’égalité stricte et donc [NaN].indexOf(NaN) === -1.

Solution proposée

Nous proposons l’ajout d’une méthode Array.prototype.includes, de sorte que les modèles ci-dessus puissent être réécrits de la manière suivante:

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

Cela a presque la même sémantique que celle ci-dessus, sauf qu'il utilise l'algorithme de comparaison SameValueZero au lieu de Strict Equality Comparison, rendant ainsi [NaN].includes(NaN) true.

Ainsi, cette proposition résout les deux problèmes rencontrés dans le code existant.

Nous avons également ajouté un paramètre fromIndex, similaire à Array.prototype.indexOf et String.prototype.includes, pour des raisons de cohérence.


Informations complémentaires:

119
Felix Kling

Si vous vous interrogez sur les performances, indexOf est plus rapide pour le moment, mais ce test JSperf a tendance à montrer que plus le temps passe, plus includes() sera plus rapide que indexOf ( Je suppose que cela sera optimisé davantage).

IMHO, je préfère aussi écrire if (arr.includes(el)) {} puisqu'il est plus clair et plus facile à gérer que if (arr.indexOf(el) !== -1) {}

9
538ROMEO

Les méthodes .indexOf() et .includes() peuvent être utilisées pour rechercher un élément dans un tableau ou pour rechercher un caractère/une sous-chaîne dans une chaîne donnée.

Utilisation dans un tableau

( Lien vers la spécification ECMAScript)

  1. indexOf utilise comparaison d'égalité stricte alors que includes utilise l'algorithme SameValueZero . Pour cette raison, les deux points de différences suivants apparaissent.

  2. Comme indiqué par Felix Kling , le comportement est différent dans le cas de NaN.

let arr = [NaN];

arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
  1. Le comportement est également différent dans le cas de undefined.
let arr = [ , , ];

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

Utilisation en chaîne

( Lien vers la spécification ECMAScript)

  1. Si vous passez une RegExp à indexOf, elle traitera la RegExp comme une chaîne et renverra l'index de la chaîne, le cas échéant. Cependant, si vous passez une RegExp à includes, une exception sera levée.
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

Performance

Comme 538ROMEO a souligné, includes peut être un peu (très minuscule) un peu plus lent (car il faut vérifier une expression régulière comme premier argument) que indexOf mais en réalité , cela ne fait pas beaucoup de différence et est négligeable.

Histoire

String.prototype.includes() a été introduit dans ECMAScript 2015 alors que Array.prototype.includes() a été introduit dans ECMAScript 2016. Pour ce qui est du support du navigateur, utilisez-les judicieusement.

String.prototype.indexOf() et Array.prototype.indexOf() sont présents dans l'édition ES5 d'ECMAScript et sont donc pris en charge par tous les navigateurs.

2
Srishti

Conceptuellement, vous devez utiliser indexOf lorsque vous souhaitez utiliser la position. IndexOf vous permet simplement d’extraire la valeur ou d’opérer sur le tableau, c’est-à-dire en utilisant slice, shift ou split après avoir obtenu la position de l’élément. D'un autre côté, utilisez Array.includes uniquement pour savoir si la valeur est à l'intérieur du tableau et non la position, car vous ne vous en souciez pas.

1
Sebastian Gomez