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

Javascript (NaN!=NaN)和(NaN!=NaN)之间有什么区别?,javascript,nan,Javascript,Nan,首先我想说的是,我知道isNaN()和Number.isNaN()是如何工作的。我正在阅读David Flanagan的明确指南,他给出了一个示例,说明如何检查值是否为NaN: x !== x 这将导致true当且仅当x为NaN时 但现在我有一个问题:他为什么要使用严格的比较?因为看起来 x != x 行为方式相同。使用这两个版本安全吗?或者我在JavaScript中缺少了一些值,这些值将返回trueforx!==对于x!=x?为了NaN的目的,=和==做同样的事情 然而,许多程序员避免使用

首先我想说的是,我知道
isNaN()
Number.isNaN()
是如何工作的。我正在阅读David Flanagan的明确指南,他给出了一个示例,说明如何检查值是否为
NaN

x !== x
这将导致
true
当且仅当
x
NaN

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

x != x

行为方式相同。使用这两个版本安全吗?或者我在JavaScript中缺少了一些值,这些值将返回
true
for
x!==对于
x!=x

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

然而,许多程序员避免使用
==
=在JavaScript中。例如,Douglas Crockford将它们视为JavaScript语言中的“”之一,因为它们的行为方式出人意料且令人困惑:

JavaScript有两组相等运算符:
==
===
=。好的按你所期望的方式工作

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


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

…我是否缺少JavaScript中的某些值,这些值将为x返回true!==x为x为假!=x

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

从定义的一开始就可以清楚地看出:

  • 返回一个brupt(x)
  • 返回初始值(y)
  • 如果类型(x)与类型(y)相同,则

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

  • 前两个步骤是基本管道。因此,实际上,
    =
    的第一步是查看类型是否相同,如果相同,则改为执行
    ==
    <代码>=
    ==只是它的否定版本

    因此,如果Flanagan是正确的,那么对于
    x!==x
    ,我们可以确定,对于
    x!=x


    许多JavaScript程序员默认使用
    ==
    ==
    为了避免松散运算符在类型强制方面存在一些缺陷,但在本例中,Flanagan对strict vs.loose运算符的使用没有任何说明。

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

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

    x != x // false
    
    但是


    我只想指出,
    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
    

    其他答案指出,<代码>=执行类型强制,但在其他语言和PAR中,标准-楠表示计算失败,并且有好的原因不等于其本身。


    由于某些原因,人们认为这是JS的问题,但是大多数有双倍的语言(即C、java、C++、C、python和其他)都表现出这种精确的行为,人们对它也很好。

    有时,图像比单词好,检查一下这个。(这就是为什么我要将此作为一个答案,而不是一个评论,因为它有更好的可视性)

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

    var f = "-1" === -1; //false
    
    而抽象相等比较(=)仅通过转换类型然后严格比较它们来检查内容*:

    var t = "-1" == -1; //true
    
    尽管在没有咨询的情况下,JavaScript在进行比较时考虑了什么还不清楚,下面的代码计算结果为true

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

    可能Flanagan只喜欢
    !==
    检查而不喜欢
    !=
    检查。据我所知,在
    x!=x
    中没有其他值。但是有两类不同的JavaScript开发人员:喜欢
    !=
    的人和喜欢
    !=
    的人,无论是为了速度、清晰度、表现力等等。为什么使用l当严格比较行为相同时选择比较?@Raulucco:
    NaN
    不是唯一的类型,而是一个数字。它是一个不等于自身的唯一值。标题似乎误导了人们。我建议将其改为“x!=x是否与x!==x不同?”femmestem:Giorgi说“在这种情况下”这是一个风格的问题。他在这一点上是正确的。当操作数的类型不同时,这不是风格,但当它们相同时,这是风格。另外:弗拉纳根正在与NaN进行这些比较,以表明NaN不等于它自己。他没有“错”他这样做是作为一个教学练习,证明它不起作用。问题不是关于NaN(尽管有标题)。问题是“我是否在JavaScript中缺少了一些值,这些值对于x!==x返回true,对于x!=x返回false?”@t.J.Crowder两个问题,真的。第一个问题是“使用两个版本安全吗?”答案是这两个版本都是等效的,我知道
     var howAmISupposedToKnowThat = [] == false; //true