首先,我想提一下,我知道isNaN()
和Number.isNaN()
是如何运作的。我正在阅读David Flanagan撰写的 The Definite Guide ,他举例说明了如何检查该值是否为NaN
:
x !== x
当且仅当true
为x
时,这将产生NaN
。
但现在我有一个问题:他为什么要使用严格的比较?因为它似乎
x != x
表现方式相同。使用这两个版本是否安全,或者我在JavaScript中遗漏了一些价值,这些价值会为true
返回x !== x
而false
会返回x != x
?
答案 0 :(得分:126)
首先,我要指出NaN
是一个非常特殊的值:根据定义,它不等于它自己。这来自JavaScript数字所依据的IEEE-754标准。 "不是数字"即使这些位完全匹配,值也永远不会等于它自身。 (它们不一定在IEEE-754中,它允许多个不同的"而不是数字"值。)这就是为什么会出现这种情况; JavaScript中的所有其他值都等于它们自己,NaN
只是特殊的。
...我错过了JavaScript中的一些值,它会为x!== x返回true而false为x!= x?
不,你不是。 !==
和!=
之间的唯一区别是,如果需要,后者将执行类型强制以使操作数的类型相同。在x != x
中,操作数的类型是相同的,因此它与x !== x
完全相同。
- ReturnIfAbrupt(X)。
- ReturnIfAbrupt(Y)。
- 的结果
如果Type(x)与Type(y)相同,那么
返回执行Strict Equality Comparison x === y。
- 醇>
...
前两个步骤是基本管道。实际上,==
的第一步是查看类型是否相同,如果是,则执行===
。 !=
和!==
只是其中的否定版本。
因此,如果Flanagan是正确的,只有NaN
才会为x !== x
提供真实,我们可以肯定只有NaN
才能为x != x
提供真实1}}。
许多JavaScript程序员默认使用===
和!==
来避免松散运算符所造成的类型强制的一些陷阱,但没有什么可以读到Flanagan的使用在这种情况下,严格与松散的运算符。
答案 1 :(得分:37)
出于NaN的目的,!=
和!==
执行相同的操作。
但是,许多程序员在JavaScript中避免使用==
或!=
。例如,道格拉斯·克罗克福德认为他们是" bad parts" JavaScript语言,因为它们以令人意想不到和令人困惑的方式运行:
JavaScript有两组相等运算符:
===
和!==
,以及它们的邪恶双胞胎==
和!=
。优秀的工作方式与您期望的方式相同。......我的建议是永远不要使用邪恶的双胞胎。相反,请始终使用
===
和!==
。
答案 2 :(得分:22)
为了好玩,让我向您展示一个人工示例x
不是NaN
,但操作员的行为却无论如何。首先定义:
Object.defineProperty(
self,
'x',
{ get: function() { return self.y = self.y ? 0 : '0'; } }
);
然后我们
x != x // false
但
x !== x // true
答案 3 :(得分:2)
我只想指出NaN
不是唯一在不使用全局对象的情况下产生x !== x
的东西。有很多聪明的方法可以触发这种行为。这是一个使用getters:
var i = 0, obj = { get x() { return i++; }};
with(obj) // force dynamic context, this is evil.
console.log(x === x); // false
正如其他答案所指出的,==
执行类型coersion,但与其他语言和标准相同 - NaN表示计算失败,并且有充分理由不等于它自己。
出于某些原因,除了我之外,人们在JS中遇到了这个问题,但是大多数具有双倍语言的语言(即C,Java,C ++,C#,Python等)都表现出这种确切的行为,而且人们也很好。
答案 4 :(得分:0)