1
votes

Polyfill for Array inclut la vérification de NaN

Tout d'abord, ce n'est pas un problème auquel je suis confronté. J'étais en train de parcourir des blogs Javascript lorsque j'ai rencontré les méthodes de prototype Array de .indexOf et .includes . Donc, si un tableau a NaN comme valeur, alors probablement indexOf ne sera pas en mesure de le comprendre et je me retrouve avec l'utilisation de .includes code>. Mais ma question ici est, puisque la compatibilité du navigateur de includes exclut en fait IE, quelle devrait être l'alternative pour détecter la vérification NaN? J'ai pensé à construire un polyfill en me référant ceci

if (Array.prototype.includes) {
  Object.defineProperty(Array.prototype, "includes", {
    enumerable: false,
    value: function(obj) {
        var newArr = this.filter(function(el) {
          return el == obj;
        });
        return newArr.length > 0;
      }
  });
}

var arr = [NaN];
console.log(arr.includes(NaN));

Mais malheureusement, il renvoie également false. Alors, quelles autres options ai-je? Ou est-ce que je rate quelque chose?


6 commentaires

Vous pouvez trouver l'index de NaN en utilisant arr.findIndex ()


Un polyfill pour includes () peut être trouvé sur MDN .


@VLAZ C'est ce que je pensais aussi au départ, mais ce n'est en fait pas le cas! Voir ecma-international.org/ecma-262/7.0/#sec -samevaluezero , NaN est la seule exception. Si x est NaN et y est NaN, renvoie true.


@CertainPerformance ouais, il semble que je me trompe ici. Pour une raison quelconque, je pensais avoir même utilisé [NaN] .includes (NaN) dans le passé et avoir obtenu false . Quoi qu'il en soit, l'implémentation MDN devrait être la bonne


Notez que votre polyfill devrait probablement changer if (Array.prototype.includes) { en if (! Array.prototype.includes) {


@CertainPerformance oui que je suis clair, je viens de supprimer la négation pour que la méthode includes exécute réellement cette partie du code et non celle par défaut.


3 Réponses :


1
votes

Vous pouvez également inclure un polyfill pour Number.isNaN , puis l'utiliser dans votre test filter - si les deux obj et el passez Number.isNaN , puis renvoyez true:

Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

// if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, "includes", {
    enumerable: false,
    value: function(obj) {
        var newArr = this.filter(function(el) {
          return el == obj || Number.isNaN(el) && Number.isNaN(obj);
        });
        return newArr.length > 0;
      }
  });
// }

var arr = [NaN];
console.log(arr.includes(NaN));


0 commentaires

1
votes

Array # includes utilise l'algorithme Same-Value-Zero, qui n'est pas identique à == .

Idem- La valeur est fournie par Object.is () , et vous pouvez rechercher manuellement -0 et +0 pour obtenir la partie «-Zéro» de la vérification. p>

La page liée comprend un polyfill, bien que puisque le polyfill inclut une étape pour rendre -0 et +0 différents - que vous ne voulez pas dans un Algorithme de même valeur zéro - vous pouvez simplement le laisser de côté et simplifier en conséquence:

function SameValueZero(x, y) {
    return x === y || (x !== x && y !== y);
}


0 commentaires

0
votes

Vous pouvez trouver l'index de NaN en utilisant firstIndex . essayez comme ceci.

var arr = [NaN];
let index = arr.findIndex(Number.isNaN)
console.log(index >= 0);


4 commentaires

Si includes doit être polyfilled, alors je doute que findIndex ou Number.isNaN soit disponible.


De plus, (index> = 0)? True: false est complètement redondant. index> = 0 renvoie un booléen, donc si le booléen renvoyé est true , le ternaire renvoie alors ... true . Et si le booléen est false , il renvoie false .


@VLAZ ohh sry je l'ai manqué !!


Bien que cela fournisse la réponse, comme @VLAZ l'a mentionné, findIndex et Number.isNaN ne sont pas pris en charge dans IE :(