Estoy familiarizado con NaN siendo "raro" en JavaScript, es decir, NaN === NaN siempre devuelve false , como se describe aquí . Por lo tanto, no se deben hacer comparaciones === para verificar NaN , sino usar isNaN(..) en su lugar.
Así que me sorprendió descubrir que
> [NaN].includes(NaN) trueEsto parece inconsistente. ¿Por qué tener este comportamiento?
¿Cómo funciona? ¿El método includes comprueba específicamente isNaN ?
Como puede ver al leer la documentación de inclusión, utiliza el algoritmo sameValueZero para funcionar, por lo que, como dice su documentación , proporciona un valor True al comparar NaN y cito:
Podemos ver en la siguiente tabla de comparaciones de igualdad que esto se debe a la forma en que
Object.ismaneja NaN. Tenga en cuenta que si Object.is(NaN, NaN) se evaluó como falso, podríamos decir que encaja en el espectro flexible/estricto como una forma aún más estricta de triple igual, una que distingue entre -0 y +0. Sin embargo, el manejo de NaN significa que esto no es cierto. Desafortunadamente,Object.istiene que ser pensado en términos de sus características específicas, en lugar de su laxitud o rigurosidad con respecto a los operadores de igualdad.
El método .includes() usa el algoritmo SameValueZero para verificar la igualdad de dos valores y considera que el valor de NaN es igual a sí mismo.
El algoritmo SameValueZero es similar a SameValue , pero la única diferencia es que el algoritmo SameValueZero considera que +0 y -0 son iguales.
El método Object.is() usa SameValue y devuelve verdadero para NaN .
console.log(Object.is(NaN, NaN)); El comportamiento del método .includes() es ligeramente diferente del método .indexOf() ; el método .indexOf() usa una comparación de igualdad estricta para comparar valores y la comparación de igualdad estricta no considera que NaN sea igual a sí mismo.
console.log([NaN].indexOf(NaN));Puede encontrar información sobre diferentes algoritmos de verificación de igualdad en MDN:
En 7.2.16 Comparación de igualdad estricta , hay la siguiente nota:
NOTA
Este algoritmo difiere del algoritmo SameValue en su tratamiento de ceros con signo y NaN.
Esto significa que Array#includes una función de comparación diferente que para una comparación estricta:
22.1.3.13 Array.prototype.incluye bajo
NOTA 3
El método include difiere intencionalmente del método similar indexOf de dos maneras. En primer lugar, utiliza el algoritmo SameValueZero , en lugar de Strict Equality Comparison , lo que le permite detectar elementos de matriz NaN . En segundo lugar, no omite los elementos de matriz faltantes, en lugar de tratarlos como indefinidos .
Según el documento de MDN dice que
Nota: técnicamente hablando, include
includes()usa el algoritmosameValueZeropara determinar si se encuentra el elemento dado.
const x = NaN, y = NaN; console.log(x == y); // false -> using 'loose' equality console.log(x === y); // false -> using 'strict' equality console.log([x].indexOf(y)); // -1 (false) -> using 'strict' equality console.log(Object.is(x, y)); // true -> using 'Same-value' equality console.log([x].includes(y)); // true -> using 'Same-value-zero' equalityObject.is() y === está en su tratamiento de los ceros con signo y los NaN.