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 five 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.

From the spec:

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:

  1. If element has a property addEventListener and its value is something truthy, it must be a function, so we’ll call it.
  2. 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();
  1. Make sure a is truthy.
  2. Make sure a.b is truthy (and thus exists).
  3. Make sure a.b.c is truthy (and thus exists).
  4. 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();
  1. Make sure a is truthy.
  2. 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.