Why are JavaScript negative numbers not always true or false?
Asked Answered
F

3

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

Can anyone explain the above output? I know I could work round this by comparing to 0 but I'm interested. I'd expect at least one of the sloppy equals statements to be true as they do implicit type conversion, and I certainly didn't expect the ternary to come up with a totally different result.

Facing answered 1/9, 2010 at 15:40 Comment(3)
@Select0r: how can -1 be === to a bool? they aren't even the same typeTarazi
@Select0r well that would definitely return false in both cases. I guess the question is really about the way the sloppy equals works.Facing
how can -1 be === to a bool? It can't, but using the type-safe comparison you'll don't have to worry about the sloppy equals.Hanshaw
M
84

In the first two cases, the boolean is cast to a number - 1 for true and 0 for false. In the final case, it is a number that is cast to a boolean and any number except for 0 and NaN will cast to true. So your test cases are really more like this:

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

The same would be true of any number that isn't 0 or 1.

For more detail, read the ECMAScript documentation. From the 3rd edition [PDF], section 11.9.3 The Abstract Equality Comparison Algorithm:

19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

It's worth giving the full algorithm a read because other types can cause worse gotchas.

Mchenry answered 1/9, 2010 at 15:42 Comment(5)
One of dynamic typing's fuzzy lines. If you know all the rules it all makes sense.Zarate
Fuzzy line indeed! Use the Boolean(-1) for a true cast the way you expect - and discover -1 is still considered true (as in not 0).Apparent
These truthy/falsy values in JS (or any other dynamic language) values are just a hindrance more than they are useful; I always now fully compare in my conditionals.Huai
If "any number except for 0 and NaN will cast to true" why does 2 == true output false ? "2" is a numberLawanda
@jackblank read again his first sentence. In your example, true is cast to 1, not 2 is cast to true This blog post is worth to read.Hombre
C
4

In most systems, non-zero values are considered a true value, but that doesn't necessarily mean that they are the same true value as true. Thus, -1 == true doesn't necessarily hold, but -1 can still be considered a true value since it is non-zero.

Really, though, you shouldn't be comparing integers to booleans if you can avoid it.

Candlestick answered 1/9, 2010 at 15:43 Comment(3)
This isn't a particularly helpful answer, since it doesn't at all address the specific oddities of JavaScript type conversion/implicit truthiness.Granado
I like this answer more than the accepted one, it explains the same thing in different oneThumbsdown
JavaScript isn't "most languages", therefor not applicable.Ruthannruthanne
C
-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!

Clarkin answered 21/4, 2016 at 11:21 Comment(1)
The explanations of == vs. === in this answer are incorrect. === is for strict type comparison, while == will attempt to auto-convert types.Supplicate

© 2022 - 2024 — McMap. All rights reserved.