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

前端 未结 5 1034
旧时难觅i
旧时难觅i 2020-12-12 13:32

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 g

相关标签:
5条回答
  • 2020-12-12 13:41

    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 !==.

    0 讨论(0)
  • 2020-12-12 13:41

    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
    
    0 讨论(0)
  • 2020-12-12 13:47

    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.

    0 讨论(0)
  • As sometimes, images are better than words, check this table (which is the reason for me to make this an answer instead a comment is because it gets better visibility).

    There you can see that strict equality comparison (===) only returns true if type and content match, so

    var f = "-1" === -1; //false
    

    While abstract equality comparison (==) checks only the content* by converting types and then strictly comparing them:

    var t = "-1" == -1; //true
    

    Though it's not clear, without consulting ECMA, what JavaScript considers when comparing, in a way that the code bellow evaluates to true.

     var howAmISupposedToKnowThat = [] == false; //true
    
    0 讨论(0)
  • 2020-12-12 13:58

    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.

    0 讨论(0)
提交回复
热议问题