Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

349
Vistas
¿Por qué [NaN].includes (NaN) devuelve verdadero en JavaScript?

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) true

Esto parece inconsistente. ¿Por qué tener este comportamiento?

¿Cómo funciona? ¿El método includes comprueba específicamente isNaN ?

over 4 years ago · Santiago Trujillo
5 Respuestas
Responde la pregunta

0

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.is maneja 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.is tiene 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.

over 4 years ago · Santiago Trujillo Denunciar

0

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:

MDN - Comparaciones de igualdad y semejanza

over 4 years ago · Santiago Trujillo Denunciar

0

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 .

over 4 years ago · Santiago Trujillo Denunciar

0

Especificaciones

Esto parece ser parte de la operación abstracta Number::sameValueZero :

6.1.6.1.15 Número::mismoValorCero ( x , y )

  1. Si x es NaN e y es NaN , devuelve verdadero .

[...]

Se requiere que esta operación sea parte de la verificación Array#includes() que hace lo siguiente:

22.1.3.13 Array.prototype.includes ( searchElement [ , fromIndex ] )

[...]

  1. Repetir, mientras k < len
    un. Sea elementK el resultado de ? Get( O , ! ToString( k )).
    B. Si SameValueZero( searchElement , elementK ) es verdadero , devuelve verdadero .
    C. Establezca k en k + 1.
  2. Devuelve falso .

[...]

Donde la operación SameValueZero se delegará a la de números en el paso 2:

7.2.12 MismoValorCero ( x , y )

[...]

  1. Si Type( x ) es diferente de Type( y ), devuelve false .
  2. Si Type( x ) es Number o BigInt, entonces
    un. Regreso ! Tipo( x )::mismoValorCero( x , y ).
  3. Regreso ! MismoValorNoNumérico( x , y ).

Para la comparación Array#indexOf() utilizará la comparación de igualdad estricta , por lo que se comporta de manera diferente:

 const arr = [NaN]; console.log(arr.includes(NaN)); // true console.log(arr.indexOf(NaN)); // -1


Otras situaciones similares

Otras operaciones que usan SameValueZero para comparar están en conjuntos y mapas:

 const s = new Set(); s.add(NaN); s.add(NaN); console.log(s.size); // 1 console.log(s.has(NaN)); // true s.delete(NaN); console.log(s.size); // 0 console.log(s.has(NaN)); // false

 const m = new Map(); m.set(NaN, "hello world"); m.set(NaN, "hello world"); console.log(m.size); // 1 console.log(m.has(NaN)); // true m.delete(NaN); console.log(m.size); // 0 console.log(m.has(NaN)); // false


Historia

El algoritmo SameValueZero aparece por primera vez en las especificaciones de ECMAScript 6, pero es más detallado. Todavía tiene el mismo significado y todavía tiene un explícito:

7.2.10 MismoValorCero( x , y )

[...]

  1. Si Tipo( x ) es Número, entonces a. Si x es NaN e y es NaN , devuelve verdadero . [...]

ECMAScript 5.1 solo tiene un algoritmo SameValue que aún trata a NaN igual a NaN . La única diferencia con SameValueZero es cómo se tratan +0 y -0 : SameValue devuelve false para ellos, mientras que SameValueZero devuelve true .

SameValue se usa principalmente para la operación de objetos internos, por lo que es casi intrascendente para escribir código JavaScript. Muchos de los usos de SameValue son cuando se trabaja con claves de objetos y no hay valores numéricos.

La operación SameValue se expone directamente en ECMAScript 6, ya que eso es lo que usa Object.is() :

 console.log(Object.is(NaN, NaN)); // true console.log(Object.is(+0, -0)); // false

De leve interés es que WeakMap y WeakSet también usan SameValue en lugar de SameValueZero que Map y Set usan para comparar. Sin embargo, WeakMap y WeakSet solo permiten objetos como miembros únicos, por lo que intentar agregar un NaN o +0 o -0 u otras primitivas genera un error.

over 4 years ago · Santiago Trujillo Denunciar

0

Según el documento de MDN dice que

Nota: Técnicamente hablando, include includes() usa el algoritmo sameValueZero para 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' equality


Explicación más detallada:

  1. La igualdad del mismo valor cero es similar a la igualdad del mismo valor , pero +0 y −0 se consideran iguales .
  2. El método Object.is() proporciona la igualdad del mismo valor : la única diferencia entre Object.is() y === está en su tratamiento de los ceros con signo y los NaN.

ingrese la descripción de la imagen aquí


Recursos adicionales:

  • ¿Qué operador es igual (== vs ===) debe usarse en las comparaciones de JavaScript?
  • Array.prototype.includes frente a Array.prototype.indexOf
  • ¿+0 y -0 son lo mismo?
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda