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

Oltre alla leggibilità migliorata, c’è qualche vantaggio includes su indexOf ? Sembrano identici a me.

Qual è la differenza tra questo

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

E questo?

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

    tl; dr: NaN è trattato in modo diverso:

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

    Dalla proposta :

    Motivazione

    Quando si utilizzano gli array ECMAScript, si desidera comunemente determinare se l’array include un elemento. Lo schema prevalente per questo è

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

    con varie altre possibilità, ad esempio arr.indexOf(el) >= 0 , o persino ~arr.indexOf(el) .

    Questi modelli presentano due problemi:

    • Non riescono a “dire cosa intendi”: invece di chiedere se l’array include un elemento, ti chiedi quale sia l’indice della prima occorrenza di quell’elemento nell’array, quindi confrontalo o bit-twiddle, per determinare la risposta alla tua domanda reale.
    • Non riescono per NaN , come indexOf utilizza il confronto rigoroso di uguaglianza e quindi [NaN].indexOf(NaN) === -1 .

    La soluzione proposta

    Proponiamo l’aggiunta di un metodo Array.prototype.includes , in modo tale che i pattern di cui sopra possano essere riscritti come

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

    Questo ha quasi la stessa semantica di quanto sopra, tranne che usa l’algoritmo di confronto SameValueZero invece di Strict Equality Comparison, rendendo così [NaN].includes(NaN) true.

    Pertanto, questa proposta risolve entrambi i problemi visti nel codice esistente.

    Aggiungiamo inoltre un parametro fromIndex , simile a Array.prototype.indexOf e String.prototype.includes , per coerenza.


    Ulteriori informazioni:

    • Algoritmo SameValueZero
    • Algoritmo di Strict Equality Comparison

    Se ti preoccupi delle performance, per il momento indexOf è più veloce, ma questo test di JSperf tende a mostrare che più passa il tempo, più includes() sarà più veloce di indexOf (credo che sarà ulteriormente ottimizzato).

    IMHO, preferisco anche scrivere if (arr.includes(el)) {} poiché è più chiaro e più if (arr.indexOf(el) !== -1) {} di if (arr.indexOf(el) !== -1) {}

    Concettualmente, dovresti usare indexOf quando vuoi usare la posizione indexOf, basta darti per estrarre il valore o operare sull’array, cioè usando slice, shift o split dopo aver ottenuto la posizione dell’elemento. D’altra parte, Usa matrice.include solo a sapere se il valore è all’interno dell’array e non la posizione perché non ti interessa.