为什么 ('0' ? 'a' : 'b') 的行为与 ('0' == true ? 'a' : 'b')

IT技术 javascript
2021-01-31 07:05:46

为什么下面两个语句的结果不同?

('0' ? 'a' : 'b') /* -> 'a' */
('0' == true ? 'a' : 'b') /* -> 'b' */

jsFiddle 测试用例

编辑:

我应该补充一点,我怀疑将 '0' 第一个语句转换为要比较的布尔值 - 这应该与“ '0' == true ”完全相同,显然这不是真的。

6个回答

首先,为了完整性:

('0' ? 'a' : 'b') 

is 'a',因为'0'一个非空字符串,它的计算结果总是true

字符串:如果参数为空字符串(其长度为零),则结果为否则结果为


现在到'0' == true.

这里将进行两种类型转换。我们可以在规范的第 11.9.3 节“抽象平等比较算法”中遵循这一点

操作数表示为xy( x == y)。

在我们的例子中,x是一个字符串 ( '0') 和y一个布尔值 ( true)。因此执行步骤 7:

如果 Type(y) 是布尔值,则返回比较结果 x == ToNumber(y)。

当布尔值转换为数字时,会发生以下转换

布尔值:如果参数为true,结果为1如果参数为false ,结果为+0

现在我们有

'0' == 1

与步骤 5 中的条件匹配:

如果 Type(x) 是 String 并且 Type(y) 是 Number,则返回 ToNumber(x) == y 的比较结果。

如何将字符串转换为数字更为复杂,但当然也可以在规范中找到

所以最后的比较是

0 == 1

false(步骤 1.a.vi.)

('0' ? 'a' : 'b'); /* -> 'a' */

0 是一个字符串值,每个非空字符串都被评估为true,而不是作为布尔值进行测试。如果引号被删除:

(0 ? 'a' : 'b'); /* -> 'b' */

您将收到 b - 现在0不是字符串并被评估为 false!

('0' == true ? 'a' : 'b'); /* -> 'b' */

0 被评估为 bool两者都被评估为数字,这是错误的。11.9.3抽象平等比较算法规格显示,可以被执行多次转换的比较同类型的变量。

实际上,您将 '0' 评估为布尔值的说法是不正确的,实际发生的情况是true被评估为一个数字,然后强制将 '0' 评估为一个数字。这是您指向的规范的直接结果。另请参阅 Felix King 的回答。
2021-03-17 07:05:46

因为'0'不等于1,所以它不等于真,虽然它不是假的。在第一种情况下,当将 '0' 强制转换为 bool 时,强制转换运算符对所有不为 0 的内容返回 true。

主要是因为 JavaScript 在真实性方面非常不一致。但答案是:

  1. 在这种情况下,'0' 被直接转换为布尔值,'0' 是一个非空字符串,为真。
  2. 在这种情况下,不会发生转换;字符串不等于布尔值。
我认为它非常一致,问题在于我们如何尝试使用它。有些东西并不像我们想象的那样使用。但所有这一切都是一个解释问题,它会导致不同的解决方案等等,而不是像数学那样的普遍真理。:)
2021-03-24 07:05:46
好吧, ('1' == true) 是真的 ;) 第二个语句中没有 ===。
2021-04-07 07:05:46
你的第二点是错误的。转换确实发生。
2021-04-08 07:05:46

那是因为'0'是真的(在 if 语句中),但不被视为等于true. 就像 3 和 17 都是真实的,但不相等。