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

First of all I want to mention that I know how isNaN() and Number.isNaN() work. I am reading The Definite Guide by David Flanagan and he gives an example for how to check if the value is NaN :

x !== x

This will result in true if and only if x is NaN .

But now I have a question: why does he use strict comparison? Because it seems that

x != x

behaves the same way. Is it safe to use both versions, or I am missing some value(s) in JavaScript that will return true for x !== x and false for x != x ?


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:

  • ReturnIfAbrupt(x).
  • ReturnIfAbrupt(y).
  • If Type(x) is the same as Type(y), then

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

  • ...

  • 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
    
    链接地址: http://www.djcxy.com/p/58500.html

    上一篇: 用于浮点相等比较的SIMD指令(NaN == NaN)

    下一篇: (NaN!= NaN)和(NaN!== NaN)之间有什么区别?