Before we continue with the “Terse JavaScript 101” series, we’re going to take a break and explore, in detail, truthy and falsey.
These are fundamental topics which I should have covered in more detail yesterday. There is copious information on this elsewhere online, so don’t feel limited to this post in your study.
Truthy: Something which evaluates to TRUE.
Falsey: Something which evaluates to FALSE.
It’s mostly logical. One (1) is truthy, Zero (0) is falsey. An object of any kind (including functions, arrays, RegExp objects, etc.) is always truthy. The easiest way to determine if something is truthy is to determine that it’s not falsey. There are only six falsey values in JavaScript:
undefined
, null
, NaN
, 0
, ""
(empty string), and false
, of course.
Note: It is possible to explicitly wrap a primitive (string, number, null, undefined, boolean) in an object, which will make it truthy. For example, 0
(zero) is falsey, but new Number(0)
is truthy. A scarier example is new Boolean(false)
which is also truthy! Be careful. Only very rarely should you need to explicitly wrap primitives.
Why should you care what’s truthy and what’s falsey?
A value’s truthi’ness determines what it will evaluate to in logical expressions. For example:
if (0) { alert('ALERT'); } |
We know that the alert()
call will never run, because 0
, being a falsey value, doesn’t satisfy the if
statement’s condition — i.e. to run only if the passed expression is NOT falsey.
The production IfStatement : if ( Expression ) Statement is evaluated as follows:
1. Evaluate Expression. 2. Call GetValue(Result(1)). ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 3. Call ToBoolean(Result(2)). ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ 4. If Result(3) is false, return (normal, empty, empty). 5. Evaluate Statement. 6. Return Result(5).
If you’re wondering, the phrase return (normal, empty, empty) essentially, means: continue with the program in a normal fashion. See 8.9 for more.
As the subtle arrows point out, the bit we’re interested in is step 3, which calls ToBoolean with the result of step 2, which is essentially (*) the value you passed in. But what is ToBoolean??
ToBoolean is simple:
Input Type | Result |
---|---|
Undefined | false |
Null | false |
Boolean | The result equals the input argument (no conversion). |
Number | The result is false if the argument is +0, -0, or NaN; otherwise the result is true. |
String | The result is false if the argument is the empty string (its length is zero); otherwise the result is true. |
Object | true |
I hope this has made it clear enough.
Enough of the spec!
We now know what happens when we pass something as an if
statement’s expression (if(..this bit..){}
), but how much relevance does truthy and falsey have in other logical contexts? Well, a lot.
Let’s explore the basic if
statement one last time though:
if (X) { // If this code runs, what have we proven about X? alert(123); } |
If 123
is alerted what can we say (for sure) about X? We can definitely say that it is NOT one of: undefined
, null
, NaN
, 0
, ""
(empty string), or false
. We can therefore say that X
is truthy. It might be the literal value true
, a number that’s not zero, an array, a function, etc.
Remember, everything in JavaScript that isn’t a primative value can be considered an object. Functions are objects. Arrays are objects. And all objects are truthy.
Since all objects are truthy, code like this is quite common:
var el = document.getElementById('foo'); if (el) { el.style.color = 'red'; } |
el
is not a boolean, it’s just an object (in this case, a DOM Element object). The if block only executes if its expression is truthy. We could be more explicit though. The getElementById
function returns null
if it doesn’t find the element, so we could do:
var el = document.getElementById('foo'); if (el !== null) { el.style.color = 'red'; } |
There’s usually little advantage in explicitly stating the falsey value that you’re looking for. Sometimes, you might want to guard against a null
or an undefined
but allow false
, for example. In such circumstances, obviously, use the explicit syntax (strict equality and strict inequality operators – ===/!==
).
The ToBoolean
thing that we referenced above happens in all logical contexts in JavaScript. For example, the &&
(logical AND) operator:
0 && alert(0); 1 && alert(1); |
In this case, only 1
will be alerted, since zero is falsey and therefore does not satisfy the &&
‘s desire for a left-hand truthy operand. The logical AND operator will only evaluate its right-hand operand if its left-hand operand is truthy.
Further up we checked that the return value of getElementById
wasn’t null by simply checking if it was truthy. If el
was truthy then we knew the element existed in the DOM and we could begin to interact with it programatically.
We use a similar concept with object access.
alert(foo.bar); // Alerting the value of the 'bar' property of 'foo' |
The only values that will throw an error when you try to access a property are null
and undefined
. So, if foo
is truthy then we can safely attempt to access it’s bar
property without worrying about exceptions being thrown.
if (foo) { alert(foo.bar); } |
Assume carefully
With our if statement we have only proven that foo
is truthy. It still might not be the object we expect. This is something to consider. Normally though, it’s safe enough to suppose that if some obscurely named value is not falsey, it’ll be the truthy value you desire and not something you don’t want.
element.addEventListener ? element.addEventListener('click', func, false) : element.attachEvent('onclick', func); |
Here we make some assumptions:
- If element has a property
addEventListener
and its value is something truthy, it must be a function, so we’ll call it. - If it doesn’t exist then
attachEvent
must exist and must be a function.
The code above happens to be working around old IE versions that don’t have the W3C DOM Event method, addEventListener
. The assumptions I’m making are considered safe in the environments that I intend my web app to operate in, but they may not be safe assumptions in other environments, so it’s important to be wary of the fact that: just because something is truthy doesn’t mean it’s the truthy value you happen to be looking for (the same goes for falsi’ness).
It’s common to attempt deep object access using the following structure:
a && a.b && a.b.c && a.b.c(); |
- Make sure
a
is truthy. - Make sure
a.b
is truthy (and thus exists). - Make sure
a.b.c
is truthy (and thus exists). - Call
a.b.c
.
Again, we’re making assumptions, but we already knew that. This structure is very useful, although too much of it can make your code bloated, so maybe consider other options. For one: consider what you CAN safely assume. In some instances, you may be able to do this:
a && a.b.c(); |
- Make sure
a
is truthy. - Call
a.b.c
.
In this example, we’ve determined that it is safe to assume that if a
is truthy, it is the very object that we’re looking for, and therefore must have a minimum structure of: a={b:{c:function(){...}}}
. We’re aware of our own data structure so can make this assumption.
Explicit booleans
You might be left wondering why we even bother having proper boolean values in JavaScript if we can get around quite easily with our other truthy and falsey values. And it’s true, we could manage without these booleans, and we rarely check for them explicitly. We usually just do something like:
if (foo.isAFoo()) { // ... } |
foo.isAFoo()
could return any truthy value (not necessarily the boolean of true
) and it would make no difference to the code execution.
But, it is important, in many situations, to be explicit in our intentions. So we should insist on using real booleans when there is a binary decision to make (two possible values).
To cast a value to its boolean representation, we can just use ToBoolean
. We can indirectly use this internal method by calling the Boolean
constructor as a function:
Boolean(0); // => false |
It will return a boolean value — either true or false, and is a really quick way of finding out whether a value is truthy of falsey:
Boolean(undefined); // => false Boolean(null); // => false Boolean(false); // => false Boolean(0); // => false Boolean(""); // => false Boolean(NaN); // => false Boolean(1); // => true Boolean([1,2,3]); // => true Boolean(function(){}); // => true |
A well-known and widely used shortcut is to use the logical-NOT operator twice, like so:
!!null; // => false !!0; // => false !!123; // => true !!'foo'; // => true |
I’ll leave that up to you to figure out 🙂
[complete!]
That’s it for today. Hopefully this has served as, at least, a minimal introduction to truthy & falsey.
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
Thank you very much for informative blog post! 🙂
pretty thorough post, and some code like “![] == []” could also be mentioned…
thanks, for beginners lesson.
thanks, I like the elaborately explained beginner lessons too!
I think it’s worth pointing out that the only string that is falsy is an empty string. The string “0” is truthy, whereas the number 0 is falsy.
This can trip people up a lot, especially when dealing with data from an HTML form, e.g. if you use “zero” as the default value for a select list. You can’t just test for truthiness if some numeric value could come to you as a string. All these are true:
Another oddity that can be confusing is that null is not coerced into a bool:
So the bottom line is, these two things ARE NOT equivalent because type coercion has different rules than truthiness:
Excellent write-up, James!
You may want to point out that
if (foo) { }
is not the same asif (foo == true) { }
. The first one doesToBoolean
coercion, while the second one doesToPrimitive
coercion. As Jamie pointed out, these are not equivalent.It’s explained in more detail here: http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
Jamie and Mathias:
Thanks for pointing this out. I’d wager
if(x)
vsif(x==true)
is the most misunderstood mainstream concept in JavaScriptFor example when
x = [];
James:
Nice article anyway!
Thanks for this and other JS articles for novices. 🙂
Truly Amazing Explanation ! Thanks !!!
You say that “A scarier example is new Boolean(false) which is also truthy!” then at the bottom of the article you say that “Boolean(false); // => false”. Would you mind explaining the difference?
Thanks for the comments!
Jamie and Mathias: excellent point about
if(x==true)
being different toif(x)
!DZ,
new Boolean
instantiates a newBoolean
object, whileBoolean
(without thenew
operator) only casts the value to a boolean (primitive).From the spec:
The comments here are just as valuable as the article itself. Thanks to the author and all contributors.
The way I think of it, truthiness/falsiness is determined when evaluating the expression and comparing it to values that could be considered “nothing.” Truth/falsity is determined by looking at whether the expression evaluates to a primitive boolean value exactly, and then comparing its value to true or false. I am still learning about this, but I don’t believe that there is any _implicit_ casting to booleans in JavaScript.
As others have said, the tricky part is that both conditional blocks and variable assignments can both use expressions that are evaluated for truthiness/falsiness (or they can use true/false boolean expressions). Once you really understand that, everything makes a little more sense.
It’s amazing the little oddities in JavaScript, which may make it more difficult to program in, but I find it more fun and in many cases it makes programming in JS have less code. The other thing I love about JS is that if I am uncertain of how a conditional will work out, I can just run it in a browser console really quick and have my answer. I suggest this trick for anyone programming in JavaScript. The console is a programmers great little friend.
Some unrelated things to say…
1. I have to say that when I saw your name in the title I read “Pseldoy” (as pseudo is falsey).
2. I have found that truthy (and falsey) are adjectives (like true) instead of nouns (like truth). That’s why I arrived at your post. I became sure when I read “the falsey value that you’re looking for”. Thank’s!
3. In Ruby I want to create an object which is falsey, but I can’t. I wish I had a ToBoolean-equivalent method to overload, but I haven’t that AFAIK.
4. Great article! I’ve appreciated it very much! Thank’s again.
5. Great comments, too! 🙂
6. I loved the moving background.
Your background is nifty. Could have been done in pure CSS though add some .js and images and it would be very nifty. Very nice site over all…Quick way to learn “truthy”
Interesting blog. Despite its many limitations JS has been very efficacious. The best part is the coding part is very less cumbersome. Thank you so much for the code here. Keep updating with more interesting stuff.
I am doing my Bachelors in Computers and studying different programming languages and concepts. Its been always very typical and confusing for me to solve truthy expressions but your article helped me a lot to understand the expression solving. Not only this article but the comments on this article also very good food for truthy-falsey expression solving, So I want to give my thanks to not only the author but to all contributors over here.
Its worth reading this article. Your this article made my concepts very clear about truthy and falsy equations that used to confuse me earlier but now I can solve these equations by my own and your article helped me a lot to understand these confusing equations. So thanks to you for helping me.
Great article.Truthy & Falsey are based on boolean logic. So to
understand truthy & falesy statement completely ,we need to
understand AND, OR and NOT also.
Best example of falsey is :
if (!y)
{
//do something
}
I have a question : Is example given below belongs to Truthy/Falsey or not? I am little confused.
if (y==7)
{
//do something
}