es8 - javascript ecmascript 2018
Array.prototype.includes vs. Array.prototype.indexOf (4)
Conceptualmente, debe usar indexOf cuando desea usar la posición indexOf solo le da que extraiga el valor u opere sobre la matriz, es decir, usando slice, shift o split después de obtener la posición del elemento. Por otro lado, Use Array.incluye solo para saber si el valor está dentro de la matriz y no la posición porque no le importa.
Más allá de la legibilidad mejorada, ¿hay alguna ventaja para
includes
sobre
indexOf
?
Me parecen idénticos.
¿Cuál es la diferencia entre esto?
var x = [1,2,3].indexOf(1) > -1; //true
¿Y esto?
var y = [1,2,3].includes(1); //true
Si se pregunta sobre las actuaciones, por el momento, indexOf es más rápido, pero esta prueba de
JSperf
tiende a mostrar que cuanto más pase el tiempo, más
includes()
será más rápido que
indexOf
(supongo que se optimizará aún más).
En mi humilde opinión, también prefiero escribir
if (arr.includes(el)) {}
ya que es más claro y más
if (arr.indexOf(el) !== -1) {}
de mantener que
if (arr.indexOf(el) !== -1) {}
.indexOf()
y
.includes()
se pueden usar para buscar un elemento en una matriz o para buscar un carácter / subcadena en una cadena dada.
Uso en matriz
( Link a la especificación ECMAScript)
-
indexOf
usa una estricta comparación de igualdad, mientras queincludes
utiliza el algoritmo SameValueZero . Por esta razón, surgen los siguientes dos puntos de diferencia. -
Como señaló , el comportamiento es diferente en el caso de
NaN
.
let arr = [NaN];
arr.indexOf(NaN); // returns -1; meaning NaN is not present
arr.includes(NaN); // returns true
-
El comportamiento también es diferente en caso de
undefined
.
let arr = [ , , ];
arr.indexOf(undefined); // returns -1; meaning undefined is not present
arr.includes(undefined); // returns true
Uso en cadena
( Link a la especificación ECMAScript)
-
Si pasa un RegExp a
indexOf
, tratará el RegExp como una cadena y devolverá el índice de la cadena, si se encuentra. Sin embargo, si pasa un RegExp a include, arrojará una excepción.
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
Actuación
Como señaló
,
includes
puede ser un poco (muy pequeño) un poco más lento (ya que necesita verificar una expresión regular como primer argumento) que
indexOf
pero en realidad, esto no hace mucha diferencia y es insignificante.
Historia
String.prototype.includes()
se introdujo en ECMAScript 2015, mientras que
Array.prototype.includes()
se introdujo en ECMAScript 2016. Con respecto al soporte del navegador, utilícelos con prudencia.
String.prototype.indexOf()
y
Array.prototype.indexOf()
están presentes en la edición ES5 de ECMAScript y, por lo tanto, son compatibles con todos los navegadores.
tl; dr:
NaN
se trata de manera diferente:
-
[NaN].indexOf(NaN) > -1
esfalse
-
[NaN].includes(NaN)
estrue
De la proposal :
Motivación
Cuando se usan matrices ECMAScript, comúnmente se desea determinar si la matriz incluye un elemento. El patrón predominante para esto es
if (arr.indexOf(el) !== -1) { ... }
con varias otras posibilidades, por ejemplo
arr.indexOf(el) >= 0
, o incluso~arr.indexOf(el)
.Estos patrones exhiben dos problemas:
- No logran "decir lo que quiere decir": en lugar de preguntar si la matriz incluye un elemento, se pregunta cuál es el índice de la primera aparición de ese elemento en la matriz y luego se compara o se divide un poco, para determinar La respuesta a su pregunta real.
- Fallan para
NaN
, ya queindexOf
usa la comparación estricta de igualdad y, por lo tanto,[NaN].indexOf(NaN) === -1
.Solución propuesta
Proponemos la adición de un método
Array.prototype.includes
, de modo que los patrones anteriores se puedan reescribir como
if (arr.includes(el)) { ... }
Esto tiene casi la misma semántica que la anterior, excepto que usa el algoritmo de comparación SameValueZero en lugar de la Comparación de igualdad estricta, lo que hace que
[NaN].includes(NaN)
verdadero.Por lo tanto, esta propuesta resuelve ambos problemas vistos en el código existente.
Además, agregamos un parámetro
fromIndex
, similar aArray.prototype.indexOf
yString.prototype.includes
, para mayor consistencia.
Más información: