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

2022-08-30 03:00:32

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

x !== x

这将导致当且仅当 是 。truexNaN

但现在我有一个问题:他为什么要使用严格的比较?因为看起来

x != x

行为方式相同。使用这两个版本是否安全,或者我在 JavaScript 中缺少一些将返回 和 for 的值?truex !== xfalsex != x


答案 1

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

...我是否在 JavaScript 中缺少一些值,这些值将返回 true 表示 x !== x,返回 false 表示 x != x?

不,你不是。和 之间的唯一区别是,如有必要,后者将执行类型强制,以使操作数的类型相同。在 中,操作数的类型相同,因此与 完全相同。!==!=x != xx !== x

抽象平等操作的定义一开始就很清楚:

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

    返回执行严格相等比较 x === y 的结果。

  4. ...

前两个步骤是基本的管道。因此,实际上,第一步是查看类型是否相同,如果是,则改为这样做。 并且只是否定的版本。=====!=!==

因此,如果 Flanagan 是正确的,那么只有会给 true for,我们可以肯定,它也是正确的,只有 会给 true for 。NaNx !== xNaNx != x

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


答案 2

为了NaN的目的,并做同样的事情。!=!==

但是,许多程序员避免使用JavaScript或JavaScript。例如,Douglas Crockford认为它们是JavaScript语言的“坏部分”之一,因为它们以意想不到的和令人困惑的方式表现:==!=

JavaScript 有两组相等运算符:和 ,以及它们的邪恶孪生和 .好的按照您期望的方式工作。===!====!=

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