Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between (NaN != NaN) and (NaN !== NaN)?

Tags:

javascript

nan

People also ask

Is NaN !== NaN?

Why NaN !== NaN. Among the many seeming oddities of JavaScript is the fact that NaN (Not-a-Number) is not equal to itself. Countless beginners have written conditionals checking if n === NaN , only to find that this is never true.

Is NaN == NaN True or False Why?

Yeah, a Not-A-Number is Not equal to itself. But unlike the case with undefined and null where comparing an undefined value to null is true but a hard check(===) of the same will give you a false value, NaN's behavior is because of IEEE spec that all systems need to adhere to.

Is NaN and NaN same in Python?

nan is NOT equal to nan At first, reading that np. nan == np. nan is False can trigger a reaction of confusion and frustration.

How do you compare NaN?

In JavaScript, the best way to check for NaN is by checking for self-equality using either of the built-in equality operators, == or === . Because NaN is not equal to itself, NaN != NaN will always return true .


First, let me point out that NaN is a very special value: By definition, it's not equal to itself. That comes from the IEEE-754 standard that JavaScript numbers draw on. The "not a number" value is never equal to itself, even when the bits are an exact match. (Which they aren't necessarily in IEEE-754, it allows for multiple different "not a number" values.) Which is why this even comes up; all other values in JavaScript are equal to themselves, NaN is just special.

...am I missing some value in JavaScript that will return true for x !== x and false for x != x?

No, you're not. The only difference between !== and != is that the latter will do type coercion if necessary to get the types of the operands to be the same. In x != x, the types of the operands are the same, and so it's exactly the same as x !== x.

This is clear from the beginning of the definition of the Abstract Equality Operation:

  1. ReturnIfAbrupt(x).
  2. ReturnIfAbrupt(y).
  3. If Type(x) is the same as Type(y), then

    Return the result of performing Strict Equality Comparison x === y.

  4. ...

The first two steps are basic plumbing. So in effect, the very first step of == is to see if the types are the same and, if so, to do === instead. != and !== are just negated versions of that.

So if Flanagan is correct that only NaN will give true for x !== x, we can be sure that it's also true that only NaN will give true for x != x.

Many JavaScript programmers default to using === and !== to avoid some pitfalls around the type coercion the loose operators do, but there's nothing to read into Flanagan's use of the strict vs. loose operator in this case.


For purposes of NaN, != and !== do the same thing.

However, many programmers avoid == or != in JavaScript. For example, Douglas Crockford considers them among the "bad parts" of the JavaScript language because they behave in unexpected and confusing ways:

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones work the way you would expect.

...My advice is to never use the evil twins. Instead, always use === and !==.


Just for fun, let me show you an artificial example where x is not NaN but the operators behave differently anyway. First define:

Object.defineProperty(
  self,
  'x',
  { get: function() { return self.y = self.y ? 0 : '0'; } }
);

Then we have

x != x // false

but

x !== x // true

I just want to point out NaN is not the only thing that produces x !== x without using the global object. There are lots of clever ways to trigger this behavior. Here is one using getters:

var i = 0, obj = { get x() { return i++; }};
with(obj) // force dynamic context, this is evil. 
console.log(x === x); // false

As other answers point out, == performs type coersion, but in as in other languages and par the standard - NaN indicates a computation failure, and for good reasons is not equal to itself.

For some reason beyond me people ocnsider this a problem with JS but most languages that have doubles (namely, C, Java, C++, C#, Python and others) exhibit this exact behavior and people are just fine with it.