javascript truthy numbers

Based on these rules:


  • false
  • 0 (zero)
  • '' or "" (empty string)
  • null
  • undefinded
  • NaN (e.g. the result of 1/0)

Truthy: Everything else

I fail to find the correct explanation as to why in following tests, only number 1 evaluates to "true"

0 == true ("false")
1 == true ("true")
2 == true ("false")
othernumber == true ("false")



The "truthy" and "falsy" rules only apply when the value itself is being used as the test, e.g.:

var str = "";
if (str) {
    // It's truthy
} else {
    // It's falsy

== has its own, different, set of rules for determining the loose equality of its operands, which are explained thoroughly in the spec's Abstract Equality Comparison algorithm:

  1. If Type(x) is the same as Type(y), then
    • Return the result of performing Strict Equality Comparison x === y.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
  10. Return false.

See the spec for the full details of the various abstract operations listed in there, although the names pretty much say what they do. (If you look at the spec, you'll see ! prior to ToNumber in various places; I've removed it above. It's not the logical NOT operator, it's a spec notation related to "abrupt completions.")

Let's follow that through for your 2 == true example:

  1. The types aren't the same, so keep going
  2. x isn't null, so keep going
  3. x isn't undefined, so keep going
  4. Type(x) is indeed Number, but Type(y) is not String, so keep going
  5. Type(x) is not String, so keep going
  6. Type(x) is not Boolean, so keep going
  7. Type(y) is Boolean, so return the result of x == ToNumber(y)
    • ToNumber(true) is 1, and since 2 == 1 is false, the result is false

But notice that step 7 is different for your 1 == true example:

  1. Type(y) is Boolean, so return the result of x == ToNumber(y)
    • ToNumber(true) is 1, and since 1 == 1 is true, the result is true

It's a very interesting reason, according to this book, when you compare anything to a boolean like you are doing, for example in x == y it follows this pattern:

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

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

Thus, when you compare 1 == true it's actually doing 1 == ToNumber(true) which then turns into 1 == 1, but when you do 2 == true it turns into 2 == 1 which is false fo course.

This and some other reasons given in the book suggest to not compare things to boolean values.

When you make a comparison to a boolean, it doesn't matter if the value itself is truthy or falsy, since it is never turned into a booleam, but the boolean is coerced into a type that can be compared to the other side of the == operator.

I hope you find this answer satisfactory.


using == is different from if(something) This test will give you your expected results:

function truthyFalsyTest()





In JavaScript (==) is an equality operator operator where type conversion is done. The more strict (===) identity operator will not do type conversion.

For example, even though a number is not a boolean, you can use a numeric value where a boolean value is expected if using the (==) operator.

But, if you enforce the stricter (===) operator, you will see that '1 === true' will evaluate to false.


Based on these rules: The issue here is that == does NOT operate by these rules. Whether something is truthy or not and how it behaves during equality tests are two different things. For the record a more correct test for truthyness would be

if (value) 
    return true;
    return false;

or even shorter - a direct conversion Boolean(value) (and the implicit conversion !!value.

However, during an equality test, both sides of == will be transformed to the same base type and then the actual test occurs. MDN has a list of rules for the conversion - straight from it a 1 == true uses a number and a boolean, therefore, the base type for both is number. The JS parser will execute ToNumber(booleanValue), so here is what the equality test actually tests

var convertedBooleanOperand = Number(true);

console.log("convertedBooleanOperand", convertedBooleanOperand);

In reality, 2 == true is converted to 2 == 1 which is false.


0 is false that doesn't mean othernumber will be true.. Simple example. If you use === in condition then you will see the false for all numbers.

(0 == true) // false
(1 == true) // true

It works fine. However, in below example, I have not used not operator (!) in the condition. So if condition is true it should print true else false. Still it will give you reverse result.

if(0){console.log("true")}else{console.log("false")} // false
if(1){console.log("true")}else{console.log("false")} // true
if(15){console.log("true")}else{console.log("false")} // true

Now if you convert numbers to Boolean then it will give the result what you were thinking.

Boolean(0) == true // false
Boolean(1) == true // true
Boolean(2) == true // true
Boolean(othernumber) == true // true



Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.