JavaScript Boolean Logic

March 1st 2013 by Samuel Rossille

If there is JavaScript in your work environment, I bet you already scratched your head in front of weird JavaScript code occurences, like

!!aBooleanValue

or this:

myNamespace = myNamespace || {};

or that:

var property = myObject && myObject.myProperty || DEFAULT_VALUE;

... and more complex multiline things.

Often perceived as ugly unclean hacks, they are just basic applications of the rules of the language. A lot of people hate this weiredness in JavaScript programs that make you feel like there are traps set up on your way just to make you suffer.

More generally we have ways of doing things in JavaScript that seem insane or in the best case just weird to a lot of people. But the only trap is that JavaScript uses the same symbols and keywords as other languages, but often with a slightly different meaning. Behind this apparent randomness there is a lot of logic and everybody can feel comfortable with it, once the logic is understood.

A good thing to start with is to understand that: In JavaScript, boolean logic has not so much to do with booleans, but more with the notion of a value being Truthy or Falsy.

Truthy and Falsy

In most languages, the if statement will require that the tested expression's type is a boolean. In javascript it can be any value. However any JavaScript value is either Truthy or Falsy.

Booleans exist, but they are just not the only values allowed to participate in a boolean operation. Now let's think about usual programming language constructs that deal with boolean logic:

All these operator are universal and have the same definition almost everywhere. In JavaScript, they are defined in quite a different way, which explain a lot of syntactic patterns that are quite funny the first time you see them but are still perfectly logical (and convenient once mastered).

The general idea, it that the boolean logic implemented in the JavaScript language strives to be as general as possible to allow the maximum flexibility. This generalisation consists in defining the operations and statements of the boolean logic in order to accept any values (not just booleans), and make these definitions compatible to what's happen in other languages when actual booleans come as inputs.

Let's start the tour...

Base operators of the boolean logic

In JavaScript, theses operators are

This can be generalized: x1 || x2 || x3 ... || xN is "the first truthy value of the list, or the last value if no truthy values is found". It's exactly the same for the && operator. Look how symetric they are: x1 && x2 && x3 ... && xN is "the first falsy value of the list, or the last value if not falsy value is found".

Important point: like in most modern programming languages, the expressions are evaluated from left to right, and we stop as soon as possible, so expressions which evaluation is not necessary to compute the result are not evaluated. As for the logical negation, it's quite simple: a boolean is not needed, but it always evaluates to a boolean. If Ais truthy, !A is false, and otherwise (when A is falsy), !A is true.

The behaviors described above explain the miscellaneous wi(l)dely used syntaxes.

Namespace declaration

windows.myNamespace = windows.myNamespace || {};

This is used when you have multiple files contributing features in the same namespace. A common practive is to declare the namespace with the line above at the beginning of all the source files that contribute to the namespace. Each time this line is executed, this happens:

So no matter the order in which the files are loaded, windows.myNamespace will always be initialized in time, and only once.

Default value

  function renderComment(author, content) {
          author = author || "Anonymous";
          content = content || "(empty)";

          // whatever
  }

This is the same pattern as above, used within the scope of a function to use a default value for a parameter of the function.

Nullity test:

myObject.myProperty && myObject.myProperty.doSomething();

Instead of

if(myObject.myProperty) {
      myObject.myProperty.doSomething();
}

you can find:

myObject.myProperty && myObject.myProperty.doSomething();

Combined usages

Let's create a dirty example:

var displayName = user && (user.displayName || "User " + user.id) || "Unknown user");

Convert to a real boolean

Now we know that we can use any value in a test. However, there are circumstances in which it's important to have a real boolean, and not a value which falsy / truthy nature will be used.

For example, let's have an object with an internal boolean property named "enabled". We also have a getter and a setter for this property. In the setter, we have an CPU - expensive task to execute, so we want to execute it only when the state actually changes. Let's write - it naively:

MyClass.prototype.setEnabled = function(enabled) {
      if(this.enabled != enabled) {
        this.enabled = enabled;
            // expensive stuff
      }
}

Doing it this way has two major issues: First, the purpose is missed: if different truthy values come successively, we will compare the values with each other and not their respective truthy / falsy natures, so the expensive process will be executed several time needlessly. Secondly, we store an object that might reference other object (and also transfer it to others if we have a getter), and in the end we can prevent garbage collection of a lot of things, which is sad because we only needed to store the truthy / falsy nature of the value. Here comes one of the most weired syntax to non javascript developers:

Here comes one of the most weired syntax to non javascript developers:

MyClass.prototype.setEnabled = function(enabled) {
        enabled = !!enabled;
        if(this.enabled != enabled) {
                this.enabled = enabled;
                // expensive stuff
        }
}

!enabled is always a real boolean, which is true if enabled is falsy and vice versa. So !!enabled is a boolean which is true when enabled is truthy and false when enabled is falsy. That’s what we wanted.

Fun stuff: the unofficial XOR operator

!A != !B

or more efficient (at least in theory) but less visually symetric:

!A !== !B

Statements that involve a boolean value for a test

The statements that involve a boolean value for a test are:

In most languages, these statements require to use a boolean for the test.

In JavaScript, these operators accept any value for the test, and the test will pass if the value is truthy, with the same behavior other that the definition for the test.

This explains these funny syntaxes you can come across:

Support test

An important part of the JavaScript development is using the browser APIs, which are partially standardized, and evole over time. So we often have to test if a feature is available and implement a graceful degradation otherwise.

The document.getSelection is a method of the document built-in onject, which is in the situation describes above. So in some browsers the document object has a method called getSelection, and it some browsers not.

if(document.getSelection) {
    var selection = document.getSelection();
    // whatever
}
else {
    // fallback
}

When the getSelection method on the document object is available in the browser, the expressiondocument.getSelection evaluates to a function (in JavaScript, functions are values too), and since the function itselt is not one of the six things that are Falsy, the test passes and we enter block where the method is actually used.

When the getSelection method on the document object is not available in the browser, the expression document.getSelection evaluates to undefined, which is falsy. Hence the execution flow goes to the else block.

for statement

for(var i = 0, item; item = myArray[i++];) {
    // do something with i and item
}

This is sometimes used to iterate over an Array which contains only truthy values.

The var i = 0, item part initializes declares the two loop variable of the loop: the index and the item.

The condition does the following things in this order:

This allows to avoid one extra line in the loop:

var item = myArray[i];

while and do … while statements, ternary operators

You can often stumble upon variants of the example used for the if ... else statement, used in the condition of a while or do ... while loop.

Some other constructs that produce boolean values.

Excluding the constructs of which we talked about before, we have in this category:

Not much fun with these ones, as they produce a regular boolean value from their input, and work as in many other languages.

Appendix: Why is something Truthy or Falsy ?

I said earlier: “Falsy values are: false, null, undefined, the empty string, the number 0, the number NaN. Everything else is truthy.”

But why this list and not an other one?

Someone used to object oriented programming can be surprised of this approach and would have probably put much fewer things in the falsy category. For example the fact that there is an empty string in a property is not like no string at all.

The list of the falsy things is much more understandable if we put thing in perspective and remember that javascript was initially designed to make minor enhancements to web pages, and most of the code was very close to DOM manipulation.

While on a web page, displaying an empty string somewhere, or not displaying a string at all has the same result. That’s why it’s understandable that the empty string has the same behavior that null and undefined when it comes to testing.

The item I agree the less with is 0, but probably it’s because of a convention as old as machine language in which 0 means false and 1 means true. Otherwise I see no reason for that, as when it comes to display, having a zero value for a numeric data is not at all having no value at all.

References and technical notes:

For a more technical overview:

I use the word “construct” to avoid saying “statement, operator, or built in function” all the time.

Additionnal sources, interesting readings and different point of views: