JavaScript中为什么负数不总是true或false?

69
-1 == true;        // false
-1 == false        // false
-1 ? true : false; // true

有人能解释上面的输出吗?我知道我可以通过与0进行比较来解决这个问题,但我很感兴趣。由于它们执行隐式类型转换,我期望至少有一个松散相等语句为真,而我肯定没有预料到三元运算符会得出完全不同的结果。


2
@Select0r:-1 怎么可能与布尔值 === 相等呢?它们甚至不是同一种类型。 - fearofawhackplanet
1
@Select0r 嗯,无论哪种情况下都肯定会返回 false。我想问题实际上是关于松散相等的工作方式的。 - Ollie Edwards
2
“-1” 怎么可能与布尔值 “===” 相等呢?它不可能相等,但是使用类型安全的比较,您就不必担心 “松散相等” 了。 - Select0r
3个回答

84
在前两种情况下,布尔值被转换为数字 - true转换为1,false转换为0。在最后一种情况下,是将数字转换为布尔值,除了0和NaN之外的任何数字都会转换为true。因此,您的测试用例实际上更像这样:
-1 == 1; // false
-1 == 0; // false
true ? true : false; // true

任何不为0或1的数字都是如此。更多细节请阅读ECMAScript文档。从第3版[PDF], 第11.9.3章 抽象相等比较算法

19. 如果y的类型是布尔型,则返回比较x == ToNumber(y)的结果。

值得一读的是完整的算法,因为其他类型可能会引起更糟糕的错误。

2
动态类型的模糊边界之一。如果你知道所有规则,一切都会变得清晰明了。 - Matthew Vines
1
确实有点模糊!使用 Boolean(-1) 进行 true 强制转换,你会发现 -1 仍然被视为 true (即非 0)。 - Rudu
这些 JS(或任何其他动态语言)中的真值/假值只是一个阻碍,而不是有用的;我现在总是在我的条件语句中进行完全比较。 - Daniel Sokolowski
如果“除了0和NaN之外的任何数字都会转换为true”,为什么2 == true输出false?“2”是一个数字。 - jack blank
1
@jackblank 再次阅读他的第一句话。在你的例子中,true 被转换为 1,而不是 2 被转换为 true。这篇博客文章值得一读。 - Fahmi

4
在大多数系统中,非零值被认为是真值,但这并不一定意味着它们与true是相同的真值。因此,-1 == true不一定成立,但-1仍然可以被认为是一个真值,因为它是非零的。
但如果可能的话,你真的不应该将整数与布尔值进行比较。

2
这并不是一个特别有帮助的答案,因为它根本没有解决 JavaScript 类型转换/隐式真值的具体奇怪问题。 - bdukes
我更喜欢这个答案,它用不同的方式解释了相同的内容。 - Marwen Trabelsi
JavaScript不是“大多数语言”,因此不适用。 - johny why

-3

When evaluated as a test condition, integers like -1, 5 and 17,000,000, all return Boolean true, because they logically evaluate to true, e.g.

if(-1) {
    "This is true";
}
else {
    "This is false";
}
=> "This is true";

(Note: 0 logically evaluates to false)

Using the "?" operator does what this code just does. It passes the first argument as a condition in an if statement, passes the second argument as the true case, and passes the third argument as the false case.

Hence the third result.


However, these integers are not of the same type as true.

True is of type Boolean, -1, 5 and 17,000,000 are of type Integer.

The comparison '==' is strict, in terms of type comparison. Even two things have the same "value", but not the same type, the "==" operator returns false:

if(6 == true) {
    "This is true";
}
else {
    "This is false";
}
=> "This is false";

Even the following will return false, because "true" is of type String and true is of type Boolean:

if("true" == true) {
    "This is true";
}
else {
    "This is false";
}
=> "This is false";

Hence, the first two results.


Note: If you'd like to compare values irregardless of type, use the "===" operator:

if(6 === true) {
    "This is true";
}
else {
    "This is false";
}
=> "This is true";

and also,

if("true" === true) {
    "This is true";
}
else {
    "This is false";
}
=> "This is true";


Hope this helps!


1
这个回答中对于 == 和 === 的解释是错误的。=== 用于严格类型比较,而 == 会尝试自动转换类型。 - cfc

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