虚假值是在布尔上下文中计算时转换为
false
的值。 https://developer.mozilla.org/en-US/docs/Glossary/Falsy
以下值恰好在Javascript中是假的:false
,0
,""
,null
,undefined
和NaN
。< / p>
现在我看到了这种奇怪的行为:只有虚假值false
,0
和""
彼此相等,但不等于其他虚假值。
此外,null
和undefined
不等于除自身以外的任何虚假值。
最后但并非最不重要的是,NaN
不等于任何虚假价值,甚至不等于它自己!
然而,所有这些都在false
if (value) { ... }
这种看似不一致的行为有什么好处或用例?
注意:“相等”是指==
运算符定义的(松散)相等,而不是===
运算符定义的严格标准。
答案 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; undefined
但NaN
=&gt; null
。同样,只有Eich可以解释为什么他认为0
应该等同于null
但0
等同于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)
我认为将false
与0
,""
,null
,NaN
或undefined
进行比较没有任何好处。在我看来,没有任何用例证明其使用是合理的。如果你正确地编写了代码,这个奇怪的行为就会被考虑在内。行为存在的原因首先是因为JavaScript是松散类型的。一切都是对象。最佳做法是避免使用==
等于运算符,而是使用===
。
从根本上说,在程序的使用过程中,你不应该允许变量被强制转换为不同的类型。它阻碍了可理解性,可读性和可维护性。明确编码布尔运算最好(即执行此if (myVar === undefined) {...}
,而不是if (!myVar) {...}
)。
答案 3 :(得分:0)
在某种程度上,不一致可能是“Wat?!?” - 见https://www.youtube.com/watch?v=FqhZZNUyVFM。
我的意思是,false
,0
和""
被认为是平等的,这有点奇怪,因为它们是不同类型的东西(好吧,我认为这很奇怪) ...但我想这就是为什么JS既有严格也有宽松的等式运算符。
这就是为什么像jshint和jslint这样的工具鼓励你只使用严格的===
运算符,所以你不要犯这种奇怪的错误。这会迫使你直接测试真实性或虚假性,而不是通过宽松的平等。
或者为了扭转它,如果你认为虚假的价值不是彼此相等是奇怪的话,如果这个不是 truthy值的行为就会很奇怪。例如,您永远不会期望"Bananas"
和"Apples"
相等。
(并且,更直接地回答你的问题:我打赌一些奇怪的历史原因可能会在JavaScript中被提及:好的部分。除此之外,我不知道。)