JavaScript — Truthy Values Don’t Always Equal True
In this article we’ll dive into the ECMAScript® 2017 Language Specification, and understand why a value can be truthy, but not coerce to loosely equal true.

Last week I posted an article: JavaScript: Can (a==1 && a==2 && a==3) ever evaluate to true? The answer is yes, it can! And there are actually quite a few different, somewhat complex ways to make it happen.
But one of the common comments on my article was that people said I neglected to mention the most simple way to make the statement true:
“This all seemed like a lot of work when
a = true
would have worked just as well”
Now, I’m not writing this article to call anyone out. In fact, it’s a very reasonable assumption that if: a = true
, and any number in JavaScript other than 0
is a truthy value, then a
should loosely equal 1
, 2
, 3
, etc…
But it doesn’t.
If you open up the developer console and type in some tests, we can in fact see that only the number 1
loosely equals true
:
true == 0; // false
true == 1; // true
true == 2; // false
true == 3; // false
true == 100; // false
true == 1000; // false
For this reason, when we attempt to set a = true
and run our equation, it naturally doesn’t work:
a = true;(a==1 && a==2 && a==3); // false
Lets explore why.
Truthy/Falsy Values in JavaScript
In JavaScript there are six falsy values:
false
0
(zero)‘’
or“”
(empty string)null
undefined
NaN
(Not a Number)
Everything else in JavaScript is Truthy. But, just because a value is truthy, doesn’t mean that it will coerce to true when testing equality.
That’s because a truthy value simply means a value that is considered true when evaluated in a boolean context (MDN).
A simple way to create a boolean context is to use an if()
statement. Take a look at the following code:
true == 2; // falseif(2){
console.log('it worked');
}// it worked
As you can see, 2
is a truthy value that doesn’t coerce to equal true
. But, because the if
statement was executed, we can see that 2
is still considered true
when evaluated in a boolean context.
Lets explore why.
Loose Equality
When working with loose equality, JavaScript uses the following set of rules to coerce values:

Recall our previous code example:
true == 2; // false
Since the x
value in our example is a boolean, this code matches up with rule #6:
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
Woah. This is huge.
When comparing a boolean and a number with loose equality, JavaScript doesn’t attempt to coerce the number. Instead, it attempts to coerce the boolean into a number!
If we now take a look at the ToNumber()
documentation, here is what we see:

We’re interested in the Boolean line — If argument is true, return 1. If argument is false, return 0. With this in mind, we can look back at our original code:
true == 2;
Becomes:
ToNumber(true) == 2;
Which becomes:
1 == 2;
And clearly, 1
does not equal 2
so we get false
!
As you can see, because it’s the boolean value that is coerced, any number other than 1
will never loosely equal true
.
Boolean Context
Lets now explore the other side of the coin. Why is the number 2
considered true when used in an if
statement?
if(2){
console.log('it worked');
}// it worked
When a number is used in a boolean context (as shown in the code above), JavaScript utilizes the ToBoolean operation to attempt to convert the number into a Boolean.
We can take a look at Section 7.1.2 of the EcmaScript Spec to see exactly what is happening:

What’s important to notice about the ToBoolean conversion chart is that the only values that will ever return false are the exact same six falsy values from our list earlier in this article. Everything else will return true.
Take a look at the Number line — If argument is +0, -0, or NaN, return false; otherwise return true. In our example, the number we are testing isn’t a zero or NAN. Because of this, true
is returned and our if
statement is allowed to execute.
Summary
The reason a truthy value can return true in a boolean context, but not coerce to equal true has to do with the implementation of JavaScript. JavaScript simply uses different operations in a boolean context versus in a coercion context.
Closing Notes:
Thanks for reading! If you’re ready to finally learn Web Development, check out: The Ultimate Guide to Learning Full Stack Web Development in 6 months.
If you’re working towards becoming a better JavaScript Developer, check out: Ace Your Javascript Interview — Learn Algorithms + Data Structures.
I publish 4 articles on web development each week. Please consider entering your email here if you’d like to be added to my once-weekly email list, or follow me on Twitter.