为什么在JavaScript中,"true" == true 的结果是false?

101

MDC对==运算符的描述如下::

如果两个操作数的类型不同,JavaScript会将操作数进行转换,然后执行严格比较。如果任何一个操作数是数字或布尔值,则尽可能将其转换为数字;否则,如果任何一个操作数是字符串,则尽可能将另一个操作数转换为字符串。

考虑到这一点,我将评估"true" == true如下:

  1. 它们是相同类型的吗?
  2. 是否有一个操作数是数字或布尔值?
  3. 我们可以将两者都转换为数字吗?不能 (isNaN(Number("true")) // true)
  4. 是否有一个操作数是字符串?
  5. 我们可以将另一个操作数转换为字符串吗?可以 (String(true) === "true" // true)

我最终得到了字符串"true""true",应该评估为true,但是JavaScript显示为false。

我错过了什么?


相关内容:http://es5.github.com/#x11.9.1 - zzzzBov
6
由于 JavaScript 的普及,世界变得更加可怕了:if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")} ---> "no yes" - user1068352
1
我必须说,我很惊讶,这太愚蠢了。这是始终始终使用 === 的另一个原因。 - B T
1
@user1068352 看看这个混乱的表格吧 :) https://dorey.github.io/JavaScript-Equality-Table/ - João Pimentel Ferreira
5个回答

102
因为"true"被转换为NaN,而true被转换为1,所以它们不同。
如您所述,两者都被转换为数字,因为至少true可以(请参见Erik Reppen的评论),然后进行比较。

1
你能告诉我步骤“我们能将两个都转换成数字吗?”什么情况下会失败吗?即使NaN也是一个数字,那么这一步怎么可能失败呢? - Isaac
6
Either vs. neither. 如果两个值都会导致 NaN,它们会转换为字符串进行比较。如果只有一个可以被转换,那么仍然进行数字比较。 - Erik Reppen
2
在 Javascript 中实际上有一些行为十分奇怪的奇特对象。例如,在 IE<9 中,当你尝试将 XML 文档转换为数字时会出现错误。 - MaxArt
你可以通过执行 Number(true)Number('true') 来自行查看转换。 - Erik Reppen

21
==比较运算符在ECMA 5中被定义为:
  1. 如果 Type(x) 是数字并且 Type(y) 是字符串,
    则返回比较 x == ToNumber(y) 的结果。
  2. 如果 Type(x) 是字符串并且 Type(y) 是数字,
    则返回比较 ToNumber(x) == y 的结果。
  3. 如果 Type(x) 是布尔值,则返回比较 ToNumber(x) == y 的结果。
  4. 如果 Type(y) 是布尔值,则返回比较 x == ToNumber(y) 的结果。

因此,"true" == true 的计算过程如下:

  1. "true" == ToNumber(true)   (通过规则7)
  2. "true" == 1
  3. ToNumber("true") == 1   (通过规则5)
  4. NaN == 1

===> false


4

我以下的推断正确吗?"true" == true 变成了 "true" == 1 然后变成了 "true" == "1"这就是为什么它们返回false? - vuquanghoang

1
等值运算符(==!=)使用抽象相等比较算法来比较两个操作数。

"true" == true

由于"true"StringtrueBoolean,我们需要返回"true" == Number(true)的结果(算法中的步骤7),即"true" == 1

"true" == 1

由于"true"String1Number,我们需要返回Number("true") == 1的结果(算法中的步骤5)。Number("true")返回NaN。 现在我们有NaN == 1
现在两个操作数都是相同类型的(Number)。根据算法,如果两个操作数都是Number,并且其中一个是NaN,则返回false(算法中的步骤1.c.i)。

0

解释一下考虑到场景true == "true"
直接运行上述代码会返回false,但是我们的期望结果是true
JavaScript使用抽象相等比较算法,所以根据该算法

true == "true"

// If one of the operands is Boolean, convert the Boolean operand to 1 if it is true and +0 if it is false
ConvertToNumber(true) == "true"

1 == "true"

// When the algorithm finds the above statements, it thinks that it needs to do one more conversion - 
// "When comparing a number to a string, try to convert the string to a numeric value"
1 == ConvertToNumber("true)
1 == NaN

// Which returns false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接