3

I'm learning about includes() feature, and I found this code

[NaN].includes(NaN) //True

But

NaN === NaN // False

Why this is posible?

  • 2
    Why shouldn't it be possible? You can easily define your own logic for comparing values: `function isSame(a, b) { return isNaN(a) ? isNaN(b) : a === b;}`. And if *you* can do that, the language can do it too. – Felix Kling Oct 19 '17 at 21:10

3 Answers3

4

Using equality NaN === NaN and using includes [NaN].includes(NaN) are basically asking two different questions:

  1. Equality - are this things that have the same name are actually equal?

NaN is an amorphic entity, which describes the concept of not being a numeric value, and doesn't actually have a value you can compare. Equality uses the Strict Equality Comparison, and defines that a comparison x === y with NaN on any side of the equation is always false:

a. If x is NaN, return false.
b. If y is NaN, return false.

  1. Includes - do I have something with that "name" in the array?

However, to search for a NaN in an array, and to keep the to Array#includes signature of passing only one param, and not a callback, we need a way to "name" what we are searching for. To make that possible, ccording to the Array#includes definition in the ECMAScript 2016 (ECMA-262) docs:

The includes method intentionally differs from the similar indexOf method in two ways. First, it uses the SameValueZero algorithm, instead of Strict Equality Comparison, allowing it to detect NaN array elements. Second, it does not skip missing array elements, instead treating them as undefined.

The definition of SameValueZero(x, y) states that when comparing:

If x is NaN and y is NaN, return true.

Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN

Unlike all other possible values in JavaScript, it is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false. Hence, the necessity of an isNaN function.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
0

[ NaN ].includes(NaN) what this does is to check if NaN is in the [ ].

NaN === NaN and NaN == NaN will still return the same value which is false. What you just have to know is that the includes methods checks if a value is the array it is been called on. Behind the hood i think the includes Array method does it's checks using typeof()

typeof(NaN) // number
[ NaN ].includes(NaN) // true

typeof("1") // string
[ 1 ].includes("1") // false

typeof(1) // number
[ 1 ].includes(1) // true

this is according to the SameValueZero Algorithm that the includes method uses. Internally it checks the type of the value

0.sh
  • 2,659
  • 16
  • 37