javascript (NaN != NaN) 和 (NaN !== NaN) 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34261938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 17:27:57  来源:igfitidea点击:

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

javascriptnan

提问by Giorgi Nakeuri

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

首先,我想提一下,我知道如何isNaN()Number.isNaN()工作。我正在阅读David Flanagan 的The Definite Guide,他举例说明了如何检查值是否为NaN

x !== x

This will result in trueif and only if xis NaN.

这将导致true当且仅当xNaN

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 truefor x !== xand falsefor x != x?

行为方式相同。使用这两个版本是否安全,或者我在 JavaScript 中遗漏了一些将返回trueforx !== xfalsefor 的值x != x

采纳答案by T.J. Crowder

First, let me point out that NaNis 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, NaNis just special.

首先,让我指出这NaN是一个非常特殊的值:根据定义,它不等于自身。这来自 JavaScript 数字所依据的 IEEE-754 标准。即使位完全匹配,“非数字”值也永远不会等于自身。(它们不一定在 IEEE-754 中,它允许多个不同的“非数字”值。)这就是为什么会出现这种情况;JavaScript 中的所有其他值都等于它们自己,NaN只是特殊的。

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

...我是否在 JavaScript 中遗漏了一些值,它会为 x !== x 返回 true 而对于 x != x 返回 false?

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.

不你不是。!==和之间的唯一区别!=是后者将在必要时进行类型强制以使操作数的类型相同。在 中x != x,操作数的类型相同,因此与 完全相同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. ...

  1. ReturnIfAbrupt(x)。
  2. ReturnIfAbrupt(y)。
  3. 如果 Type(x) 与 Type(y) 相同,则

    返回执行严格相等比较 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 NaNwill give true for x !== x, we can be sure that it's also true that only NaNwill give true for x != x.

因此,如果 Flanagan 是正确的 only NaNwill give true for x !== x,我们可以肯定它也是 true only NaNwill 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.

许多 JavaScript 程序员默认使用===!==避免围绕松散运算符所做的类型强制的一些陷阱,但在这种情况下,Flanagan 对严格与松散运算符的使用没有什么可阅读的。

回答by jkdev

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

出于 NaN 的目的,!=!==做同样的事情。

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 中。例如,Douglas Crockford 将它们视为JavaScript 语言的“坏部分”,因为它们的行为方式出乎意料且令人困惑:

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

JavaScript 有两组相等运算符:===and !==,以及它们的邪恶双胞胎==and !=。好的方法会按照您期望的方式工作。

...我的建议是永远不要使用邪恶的双胞胎。相反,请始终使用===!==

回答by GOTO 0

Just for fun, let me show you an artificial example where xis not NaNbut the operators behave differently anyway. First define:

只是为了好玩,让我向您展示一个人工示例,其中x不是,NaN但无论如何操作符的行为都不同。首先定义:

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

Then we have

然后我们有

x != x // false

but

x !== x // true

回答by Benjamin Gruenbaum

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

我只想指出NaN不是唯一x !== x不使用全局对象产生的东西。有很多聪明的方法可以触发这种行为。这是一个使用 getter 的方法:

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.

正如其他答案所指出的那样,==执行类型强制,但在其他语言和标准中一样 - NaN 表示计算失败,并且出于充分的理由不等于自身。

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.

出于某种原因,除了我,人们认为这是 JS 的一个问题,但大多数具有双精度的语言(即 C、Java、C++、C#、Python 和其他)都表现出这种确切的行为,人们对此很好。

回答by MVCDS

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

在那里您可以看到严格相等比较 (===) 仅在类型和内容匹配时才返回 true,因此

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.

虽然不清楚,但不咨询ECMA,JavaScript 在比较时会考虑什么,下面的代码评估为 true。

 var howAmISupposedToKnowThat = [] == false; //true