— JavaScript — 2 min read
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 ( || ).
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:
1function loadContent( area, cachePage, cache ){2 if ( typeof editMode === "undefined") {3 if ( isdlg !== '' || isdlg !== undefined || isdlg !== null ) {4 if ( cache === true ) ) {5 content = get( area.id ) );6 if ( cachePage === false ) ) {7 content = null;8 }9 }10 }11 }12 return content;13}
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:
editMode
variable is undefined and...isdlg
variable is not a falsey value and...cache
is true, then get( area.id )
.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.
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:
1(cachePage === false) && content = null;
Or, let's just "not" our cachePage variable like this:
1!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:
1function loadContent ( area, cachePage, cache ) {2 // just shortening the code with these variables3 var ed = !!(typeof editMode === "undefined"),4 d = !!(isdlg),5 id = area.id,6 content = null;78 content = ed && !d && !cachePage && cache && get( id );9 return content;10}
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:
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.get(id)
.Nice and simple! If you prefer to use an if
statement, you could write it like this:
1content = null;2 if ( ed && !d && !cachePage && cache ) {3 content = get( id );4 }
I personally like using the logical &&; it's more consise with less typing as well.
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:
1function get ( id ) {2 var el;3 if (id === '' || id === undefined || id === null) {4 el = document.getElementById('#default');5 } else {6 el = document.getElementById( id );7 }8 return el;9}
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:
1function get ( id ) {2 return document.getElementById( id || '#default');3}
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.
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!
'Til next time,
-G