JavaScript Short Circuiting: Using And/Or Instead of If-Else

The And && and Or || operators have a cool trick in Javascript. They don’t necessarily evaluate to a strict true or false boolean. Instead, they can evaluate to something that is truthy or falsy. If you’re not familiar with truthy and falsy, you can read more about it here.

Or Operator

The Or operator will evaluate to the first truthy value or the last falsy value. Once it finds either of those things it will not run any other code in the conditional.

The Or operator is like looking at a restaurant menu when you’re not picky. Once you find one thing you like, you stop and order that. If you get all the way to the bottom and don’t find anything you like, you just order the last thing on the menu.

So for each of these conditionals it will evaluate to the bolded value and it won’t even look at the code that is crossed out.

true || false || true
false || true || false
true || true || true
false || false || false

"banana" || "apple"
0 || 53 || 27
"cake" && undefined && "cookies"
undefined || null

And Operator

The And operator will evaluate to the first falsy value or the last truthy value. Once it finds either of those things it will not run any other code in the conditional.

The And operator is like looking at an ingredients list when you’re picky. Once you find one thing you don’t like, you stop and complain about that. If you get all the way to the bottom and don’t find anything you don’t like, you just complain about the last thing because complaining is fun.

So for each of these conditionals it will evaluate to the bolded value and it won’t even look at the code that is crossed out.

true && false && true
false && false && false
true && true && true
true && true && false

"banana" && "apple"
0 && 53 && 27
"cake" && undefined && "cookies"
undefined && null

Short-Circuiting

An important part to pay attention to is that the And and Or operators are lazy. Once they find something that tells them what they need to know, they are so lazy they stop and just evaluate to that. They don’t even look at anything else in the conditional. We call this short-circuiting.

When the Or operator is looking at this conditional:

0 || 53 || 27

It first checks the zero, which is falsy, and for Or that’s not helpful information. The conditional could still evaluate to truthy or falsy regardless.

Then it checks the 53, which is truthy. That is helpful information! In an Or, if there’s one thing that’s truthy, it will evaluate to truthy. It doesn’t matter what else there is.

So the Or stops and evaluates to 53. It short-circuits.

When the And operator is looking at this conditional:

"cake" && undefined && "cookies"

It first checks “cake”, which is truthy, and that doesn’t tell And whether this needs to evaluate to truthy or falsy.

Then it checks the undefined, which is falsy. Now it knows that it needs to return falsy, so it stops and evaluates to undefined. It short-circuits and never even considers “cookies” (which is a shame).

This also means that if we’re calling a function or doing an operation later in a conditional, short-circuiting could mean it never runs at all. Neither of these lines will alert anything:

true || alert("This alert won't run")
false && alert("Neither will this one")

This can end up being very useful.

How Can We Use This With the Or Operator?

Consider this conditional:

"good morning" || "hello"

It evaluates to the string "good morning", which is truthy. If we put that conditional in an if, it would work the same as if it evaluated true:

if("good morning" || "hello") {
  console.log("This line will run");
}

But if we put it outside an if, we get a cool feature.

const greeting = "good morning" || "hello";

This will always set the greeting variable to “good morning”. Not cool yet.

But what if we do this?

const defaultGreeting = "hello";

function greet(customGreeting) {
  alert(customGreeting || defaultGreeting);
}

Now if we call the greet function like this:

greet("good morning")

We’ll get an alert that says “good morning”.

And if we call it like this:

greet("hola")

We’ll get an alert that says “hola”.

But if we call it like this:

greet()

We’ll get an alert that says “hello”.

We built in a check that uses the first value if it’s truthy (in this case, if the parameter is defined) or a default value if the first value is falsy (in this case, if there wasn’t a parameter given).

I happen to think that’s pretty cool 😎

We could write it as an if/else, maybe like this:

const defaultGreeting = "hello";

function greet(customGreeting) {
  if(customGreeting) {
    alert(customGreeting);
  }
  else {
    alert(defaultGreeting)
  }
}

But it’s definitely not as cool 😏

Other Examples with Or

There are countless ways to use this helpful feature with the Or operator, here are a few:

To not do extra work:

const thing = lookInOnePlace() || lookInAnotherPlace() || "couldn't find it"

The second function that looks in another place will only run if the first one didn’t find anything (aka, returned something falsy). If neither of them return something truthy, then it will put the string "couldn't find it" in the thing variable.

To try things until something works:

planA() || planB() || planC()

This code will try each function until one returns a truthy value.

To show an error if something didn’t work:

alert(getMessage() || "there was a problem getting the message")

If getMessage() returns something falsy, this line will alert out "there was a problem getting the message".

How Can We Use This With the And Operator?

Let’s look at another conditional:

{ amount: 6 } && 2 && 6 / 2

Looks kind of strange. Why would we do this?.

const numberOfCookies = { amount: 6 } && 2 && 6 / 2

Okay, this is just always going to set numberOfCookies to 3, because 6 divided by 2 is 3. Still doesn’t seem that useful.

But what if we do this?

function splitBoxOfCookies(box, numberOfPeople) {
  return box && numberOfPeople && box.amount / numberOfPeople
}

Now it’s doing some validation for us.

Because if we just do this:

function splitBoxOfCookies(box, numberOfPeople) {
  return box.amount / numberOfPeople
}

Then if this function is ever not given a box:

splitBoxOfCookies(null, 3);

It would error out.

And if it’s given zero for the number of people:

splitBoxOfCookies({ amount: 4 }, 0)

It would return Infinity which, while it sounds exciting, probably isn’t what we want it to do.

If we wanted, we could use if/else-if/else to do the same thing as our And code:

function splitBoxOfCookies(box, numberOfPeople) {
  if(!box) {
    return box;
  }
  else if(!numberOfPeople) {
    return numberOfPeople;
  }
  else {
    return box.amount / numberOfPeople;
  }
}

The code above will behave the same as the code below:

function splitBoxOfCookies(box, numberOfPeople) {
  return box && numberOfPeople && box.amount / numberOfPeople
}

But with much less ✨ sparkle ✨

Other Examples With And

Some common ways of using short-circuiting with And are:

To make sure you’re working with an array before you try to manipulate it:

Array.isArray(messageList) && messageList.sort()

This will only call .sort() on the messageList variable if there is an array inside of it. It helps us avoid erroring out.

To make sure an object isn’t null/undefined before you try to access properties on it:

const zipCode = user && user.address && user.address.zipCode

This code will set zipCode to null or undefined if user or user.address are null or undefined, rather than erroring out.

To conditionally show something:

emailList.length === 0 && "You have no emails in your inbox"

This will either evaluate to false if the list of emails isn’t empty, or to the string “You have no emails in your inbox” if the list of emails is empty. This can be particularly helpful when conditionally showing content in JSX, since JSX ignores false.

Leave a Reply

Your email address will not be published. Required fields are marked *