Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

347
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!