首先,我想提一下,我知道如何 isNaN()
和 Number.isNaN()
工作 . 我正在阅读David Flanagan的The Definite Guide,他给出了一个如何检查值是否为 NaN
的示例:
x !== x
当且仅当 x
为 NaN
时,这将导致 true
.
但现在我有一个问题:他为什么要使用严格的比较?因为它似乎
x != x
表现方式相同 . 使用这两个版本是否安全,或者我在JavaScript中遗漏了一些值,这些值将返回 x !== x
为 x !== x
和 false
为 x != x
?
5 回答
首先,我要指出
NaN
是一个非常特殊的值:根据定义,它必须在IEEE-754中,它允许多个不同的"not a number"值 . )这就是为什么会出现这种情况; JavaScript中的所有其他值都等于它们自己,NaN
只是特殊的 .不你不是 .
!==
和!=
之间的唯一区别是,如果需要,后者将执行类型强制以使操作数的类型相同 . 在x != x
中,操作数的类型是相同的,因此它与x !== x
完全相同 .从Abstract Equality Operation定义的开头就可以看出这一点:
前两个步骤是基本管道 . 所以实际上,
==
的第一步是查看类型是否相同,如果是,则执行===
.!=
和!==
只是其中的否定版本 .因此,如果Flanagan是正确的,只有
NaN
将为x !== x
赋予真,那么我们可以确定只有NaN
才会为x != x
赋予真 .许多JavaScript程序员默认使用
===
和!==
来避免松散运算符所做的类型强制的一些陷阱,但是在这种情况下使用了严格与松散运算符 .出于NaN的目的,
!=
和!==
做同样的事情 .但是,许多程序员在JavaScript中避免使用
==
或!=
. 例如,道格拉斯·克罗克福德认为它们属于JavaScript语言的“bad parts”,因为它们表现出意想不到的混乱方式:只是为了好玩,让我向您展示一个人工示例,其中
x
不是NaN
但操作员的行为却无论如何 . 首先定义:然后我们有
但
我只是想指出
NaN
不是唯一不使用全局对象产生x !== x
的东西 . 有很多聪明的方法可以触发这种行为 . 这是使用getter的一个:正如其他答案所指出的那样,
==
执行类型coersion,但与其他语言和标准相同 - NaN表示计算失败,并且有充分理由不等于它自己 .由于某些原因,除了我之外,人们用JS来解决这个问题,但是大多数具有双倍语言的语言(即C,Java,C,C#,Python等)都表现出这种确切的行为,人们对它很好 .
有时,图像比单词更好,检查这个table(这是我做出这个答案而不是评论的原因,因为它获得了更好的可见性) .
在那里你可以看到严格的相等比较(===)只有在类型和内容匹配时才返回true,所以
虽然抽象相等比较(==)仅通过转换类型检查内容*,然后严格比较它们:
虽然不清楚,但是在没有咨询ECMA的情况下,JavaScript在比较时会考虑什么,以及代码如下评估为真的方式 .