d

Even shorter conditionals with short-circuiting

The benefit of short-circuiting

In this tip, you’ll learn to reduce conditionals to the smallest possible expression with short circuiting.

You’ve been simplifying conditional expressions a lot in the last few tips. But there’s one more level of simplification you can use: short circuiting.

As the name implies, the goal of short circuiting is to bypass information checks by placing the most relevant information first.

Let’s ask our user their name and if it’s a valid name, meaning not an empty string, we’ll set that equal to their username. Otherwise, we’ll judge them anonymous and give them the username guest. We’ll store that username as a variable. How would we write this out as an if statement?

const response = "Reed";

let username;

if (response) {
  username = response;
} else {
  username = "guest";
}

console.log(username);

|| short-circuiting

Consider the following ternary, which would fit in well with the discussion from the previous chapter.

const response = 'Reed';const​ name = response ? response :'guest';
​console.log(name);

The goal here is fairly clear. If the user provides a name to the prompt (in this case, that means it’s defined and isn’t an empty string), then you want to use that name. If it’s falsy, such as undefined, or ”, then you want to use the default name, 'guest'.

You probably noticed that you’re writing the information check, response, twice. Let’s assume that data is always going to be valid, which means there’s no difference between the information we’re checking and the information we want. If it’s truthy, we’re going to use it.

Before updating the code, take a moment to think about how logical operators work. The or operator, symbolized as ||, will return true if any of the possible values are true. That means that as soon as one thing—anything—returns true, you don’t care what the other values might be.

Now here’s where it gets interesting. Because you can use truthy values to test a Boolean expression, true or false, there’s no incentive for the language to change the value from something truthy to true. So if one value in an || check returns true, you get that truthy value and not true.

Let’s see this in action. If we have a valid name, which is a string and not a falsy value, we’ll get that put in our variable

const username = "Reed" || "guest";
console.log(username); // 'Reed'

Now you have all of the tools you need to rewrite the ternary to something concise.

const response = "Reed";const​ username = response ||'guest';
​console.log(username);

As you may have noticed, the best part is that you can append a default value to the end of the expression. This means that you never have to worry about a variable being falsy because you know there’s a truthy value waiting at the end.

There you have it. You can use short circuiting to bypass information once something truthy occurs. How about the other way around? How can you halt an expression once something false occurs? That’s possible as well.

Another popular usage of short circuiting is to check multiple conditions.

&& short-circuiting

What if we are checking for a valid user, and on top of the user having a name as well as having verified their email. If not, then they are a guest. How can we check to make sure that both conditions are true—a valid name and a verified email?

Let’s write this out in the long format with if statements and we’ll store whether the email is verified in a variable, isEmailVerified. Let’s say we have a name and the email is verified:

const response = "Reed";
const isEmailVerified = true;

let username;

if (response) {
  if (isEmailVerified) {
    username = response;
  }
} else {
  username = "guest";
}

console.log(username);

Again, this is a bit verbose. Fortunately, short circuiting can help. Combining conditionals with the && operator will us to combine the two if conditionals into one.

How does the && operator work? A logical string built with an && operator will cease as soon as a false value occurs and will return the second value if true:

For example:

const username = "guest" && "A better name";
console.log(username); // ‘A better name’

But if we turn the first value on the left side to a falsy value (an empty string), the conditional exists and returns the falsy value.

const username = "" && "A better name";
console.log(username); // ‘’

So how does this help us? For the &&, if the first condition is true it moves onto the next, so instead of having multiple if statements, we can join them all with &&. So let’s rewrite what we had:

const response = prompt("What’s your name?");
const isEmailVerified = true;

let username;

if (response && isEmailVerified) {
  username = response;
} else {
  username = "guest";
}

console.log(username);

This is significantly shorter, and then using the ternary operator we can make it even shorter. But knowing now how && works, by returning the second operand, we need to put response second:

const response = "Reed";
const isEmailVerified = true;

// prettier-ignore
const username = isEmailVerified && response || 'guest';
console.log(username);

Operator precedence

When it comes to short circuiting, it can be very powerful, but be aware of operator precedence. This means the order in which operators are performed. Do you know whether conditionals with && or || operators are executed first?

&& has higher precedence than ||, so it will always be executed first. You can either keep this in mind when writing your conditionals, or you can set which operators will be executed first using parentheses. For example, if you want to the || conditional to be executed first, you can wrap that part in parentheses, since parentheses have the highest precedence of all operators in JavaScript:

const username = isEmailVerified && (response || "guest");

Use short-circuiting with caution

Be careful when combining ternaries and short circuiting. Things can get out of hand very quickly. Though the code is terse, it may be hard for other programmers to understand.

There’s no explicit rule about how many conditionals are too many. It’s more a matter of taste and team agreement. But when things get long (usually around three conditional checks), it’s better to make it a standalone function.

Simplicity is great. And it’s fun to try and find clever ways to reduce things to one line. But the goal is always communication and readability. Use short circuiting to make things readable—not to make code artificially small.