为什么JavaScript中的虚假值不相等?

时间:2015-06-23 14:33:52

标签: javascript

  

虚假值是在布尔上下文中计算时转换为false的值。   https://developer.mozilla.org/en-US/docs/Glossary/Falsy

以下值恰好在Javascript中是假的:false0""nullundefinedNaN。< / p>

现在我看到了这种奇怪的行为:只有虚假值false0""彼此相等,但不等于其他虚假值。

此外,nullundefined不等于除自身以外的任何虚假值。

最后但并非最不重要的是,NaN不等于任何虚假价值,甚至不等于它自己!

然而,所有这些都在false

之类的布尔表达式中评估为if (value) { ... }

这种看似不一致的行为有什么好处或用例?

注意:“相等”是指==运算符定义的(松散)相等,而不是===运算符定义的严格标准。

4 个答案:

答案 0 :(得分:7)

  

为什么JavaScript中的虚假值不相等?

因为当用作布尔值时两个值强制相同的值之间存在差异,并且这两个值彼此相等。

  

这种看似不一致的行为有什么好处或用例?

在那里,我们进入了主要的主观领域,这对于SO来说并不是真正的主题。让我们说,JavaScript的松散平等规则长期以来一直是争论和混乱的主题。人们必须记住,他们是由布兰登·艾希(Brendan Eich)在1995年5月疯狂的10天中创造的,他创造了JavaScript,在那里有一些“clangers”并不奇怪。并且记住他的任务是为非程序员创建一个容忍,宽容的语言。因此,自动分号转换,松散的等式,等等。这是一种语言,旨在让您从input中获取值并将其视为数字,即使value的{​​{1}}始终为字符串。这些规则是否达到了这个目标是一个意见问题(我不会在这里推进一个方式:-))。

大多数“怪异”都是作为规则的副产品,而主要似乎是合理的(再次,有几个支柱)。让我们考虑input为真的事情:

"" == 0的规则是abstract equality comparison algorithm,它表示如果第一个操作数(==)是字符串而第二个操作数(x)是一个数字,我们返回y的结果。撇开一个强制平等算子是否是一个好主意的问题,如果你想要一个,这似乎是一种合理的方式来接近ToNumber(x) == y。因此,我们查看ToNumber算法,该算法表示string == number使用ToNumber Applied to the String Type algorithm将字符串解释为数字,其中包括空字符串变为ToNumber(string)

所以问题不是“为什么0等于""”,而是“为什么0在被视为数字时强制转换为""? “只有Eich可以回答这个问题。 : - )

主ToNumber算法中还有其他一些有趣的算法,例如0 =&gt; undefinedNaN =&gt; null。同样,只有Eich可以解释为什么他认为0应该等同于null0等同于undefined

值得注意的是,他可能不会随意挑选这些东西。他研究了其他几种语言并根据这些知识做出了选择。回想起来,其中一些选择对我们来说可能看起来很奇怪(implicit globals?真的?),但是,大多数人有超过10天的时间来创建一种语言,他们可以在这段时间内寻求同事和社区的意见。而且,还有那种“宽容”的设计标准。

我可能在那里误入了一些主观性。如果是这样的道歉;我尽力不去。 : - )

最后的注意事项:如果您发现规则是任意且难以记忆的,那么您并不孤单。处理这种情况的一种方法是确保您明确地执行所有类型强制 。但请注意,即使你试图这样做,你也会陷入松散的比较,因为虽然有一个严格的相等运算符(NaN)和一个严格的不等运算符(===),但没有严格的版本!==><>=。因此,如果您错过了明确的强制,那么如果您正在执行其他任何关系,您的代码似乎仍然有用。我不是在鼓吹这一点(也不是我提倡反对它),我已经看到了由明确的类型强制和没有明确的类型强制引起的错误。只是说这是处理棘手规则的一种方法。

答案 1 :(得分:1)

这可能与偏好有关。 == null非常有用,可以确定某些内容是否在&#34;未设置&#34; state,因为它也检查undefined;但对""0等值不返回true;它通常会从表单中作为有效值返回。

我的理解是NaN未能通过所有比较检查,以便尽快注意到它,以便表示&#34;这是您期望的值。 &#34;如果某人的类型检查块以else { throw exception because I don't know what this is! }

结尾,则可以解决此问题

答案 2 :(得分:1)

我认为将false0""nullNaNundefined进行比较没有任何好处。在我看来,没有任何用例证明其使用是合理的。如果你正确地编写了代码,这个奇怪的行为就会被考虑在内。行为存在的原因首先是因为JavaScript是松散类型的。一切都是对象。最佳做法是避免使用==等于运算符,而是使用===

从根本上说,在程序的使用过程中,你不应该允许变量被强制转换为不同的类型。它阻碍了可理解性,可读性和可维护性。明确编码布尔运算最好(即执行此if (myVar === undefined) {...},而不是if (!myVar) {...})。

答案 3 :(得分:0)

在某种程度上,不一致可能是“Wat?!?” - 见https://www.youtube.com/watch?v=FqhZZNUyVFM

我的意思是,false0""被认为是平等的,这有点奇怪,因为它们是不同类型的东西(好吧,我认为这很奇怪) ...但我想这就是为什么JS既有严格也有宽松的等式运算符。

这就是为什么像jshint和jslint这样的工具鼓励你只使用严格的===运算符,所以你不要犯这种奇怪的错误。这会迫使你直接测试真实性或虚假性,而不是通过宽松的平等。

或者为了扭转它,如果你认为虚假的价值不是彼此相等是奇怪的话,如果这个不是 truthy值的行为就会很奇怪。例如,您永远不会期望"Bananas""Apples"相等。

(并且,更直接地回答你的问题:我打赌一些奇怪的历史原因可能会在JavaScript中被提及:好的部分。除此之外,我不知道。)