And-ing and Or-ing your way to better code

I have recently been optimizing a javascript file that I wrote a while back and at the time I didn't understand logical ands ( && ) and ors ( || ).

The Logical && replaces the simple if

You can think of the && as a drop-in replacement for an if statement that has no else statement. So if something is true then do something else. Going over my code I ran into this horrible mess:

function loadContent( area, cachePage, cache ){
  if ( typeof editMode === "undefined") {  
    if ( isdlg !== '' || isdlg !== undefined || isdlg !== null ) {  
      if ( cache === true ) ) {
        content = get( area.id ) );  
        if ( cachePage === false ) ) { 
          content = null;
        }
      }
    }
  }
  return content;
}

WOW.... I was shocked ( at least I used a === )! This code screams for a total refactoring. This was a great situation to use a logical &&.

As an explanation, here is how this code reads:

  • If the editMode variable is undefined and...
  • If the isdlg variable is not a falsey value and...
  • If cache is true, then get( area.id ).
  • But if cachePage is false, re-set content=null.

Far from the best code in the world. Why on earth did I call a function to set a variable and then set it back to null if a simple check failed? Damn stupid of me.

Lets start with a simple example

In the last if statement in this example, we are checking that the cachePage variable is false and, if it is, setting our content = null;. Simple enough. But with a logical && our code gets much more succinct. We just && our check with our "truthy" result. Like so:

(cachePage === false) && content = null;

Or, let's just "not" our cachePage variable like this:

!cachePage && content = null;

Much cleaner! So how does this work? In a nutshell, the JavaScript engine checks the value on the left side of the &&. If this value is true or truthy, then it will check/execute the right side.

So I cleaned up the rest of the code this way. Replacing my premature function call along the way. I came away with the following code which works the exact same:

function loadContent ( area, cachePage, cache ) {   
    // just shortening the code with these variables
    var ed = !!(typeof editMode === "undefined"),
        d = !!(isdlg),
        id = area.id,
        content = null;

    content = ed && !d && !cachePage && cache && get( id );
    return content;
}

If any step along the chain is false then the content variable is untouched and remains set to null. If however each step is true, the content will be set to the result of the get( id ) function.

The resulting code is similar to the original code:

  • The ed variable returns true if the editMode variable is undefined.
  • !d returns true if the isdlg variable is falsey.
  • !cachePage returns true if cachePage is falsey.
  • cache returns true if cache is truthy.
  • If eveything above is true, get(id).

Nice and simple! If you prefer to use an if statement, you could write it like this:

content = null;
if ( ed && !d && !cachePage && cache ) { 
    content = get( id ); 
} 

I personally like using the logical &&; it's more consise with less typing as well.

Logical || and setting a default value

The Logical || is also very useful. Before I learned how to use this I had a lot of boilerplate code in every function. Here is an example I found in my old code:

function get ( id ) {
    var el;
    if (id === '' || id === undefined || id === null) {
        el = document.getElementById('#default');
    } else {
        el = document.getElementById( id );
    }
    return el;
}

Pretty straight forward code. If the functions receives an id then select that element. If not, the select the #default element. Using the logical || we can simplify this code and make it DRYer:

function get ( id ) {
    return document.getElementById( id || '#default');
}

Again this is functionaly the same as the previous example but is much more consise. Like the logical &&, the logical || checks the left hand side first but in the case of the || it checks for a falsey value. So if this is a falsey value, the left side is checked/executed. So, in this example, if the value #me was passed to the id variable, then it would be truthy and that element would be selected. If, however, id was not passed then it would be falsey and the left side would get checked, thus the #default element would be selected.

Conclusion

I hope this helps someone else understand these two very powerful features of JavaScript. I know they have made my code much more consise and consistent not to mention quicker!