What is short circuiting?
06 Apr 2019Short circuiting in JavaScript (and other languages) is when only part of a boolean expression is evaluated in order to get the result of the entire expression.
Say you have some boolean logic with 3 conditions, where
each condition needs to evaluate to true
in order for the entire
expression to also be considered true
. If the first condition is true
,
but the second one is false
, then we don’t need to know the
value of the 3rd condition in order to determine that the result of the entire
expression is actually false
. That’s short circuit evaluation.
Examples
Below we have a boolean AND expression with 3 conditions, which all need to be true
in
order for the entire expression to also be considered true
.
if (5 > 2 && 1 > 100 && 4 > 3) {
console.log('Hey, the expression is true!')
} else {
console.log('The expression is false!')
}
When evaluating expressions like this, the JavaScript engine will go from left to right, like so:
- Is 5 > 2? Yes it is, so let’s check the next condition.
- Is 1 > 100? Nope, stop right here. The entire expression is
false
. - Now we jump to the
else
branch, andconsole.log('The expression is false!')
runs.
In this case, the check for 4 > 3
never runs. The JavaScript engine
doesn’t want to do more work than it needs to in order to get the value of the
entire expression, so it short circuits.
This example only used &&
(AND) operators, so any of the conditions
evaluating to false invalidates the entire expression. Short circuiting also
works with the ||
(OR) operator as well, though.
Take this code for example:
if (1 > 100 || 5 > 2 || 4 > 3) {
console.log('Hey, the expression is true!')
} else {
console.log('The expression is false!')
}
Since we’re now using an OR operator, only 1 of the conditions needs to be
true
before we can safely say that the entire expression is also
true
.
The JavaScript engine, going from left to right will now do this:
- Is 1 > 100? Nope, let’s move on.
- Is 5 > 2? Yup, we’re done here. No need to look at the rest of the conditions.
- Run
console.log('Hey, the expression is true!')
Why is this useful?
Short circuit evaluation is a JavaScript language feature that’s super useful, for a variety of reasons that are non-exhaustively listed here:
1. Error handling and safety checks
During the execution of a program, whether or not an object is null
or undefined
may not be known. Let’s pretend we have a function
that may return a Food object, but it may also potentially return null
.
We may naively check if the food object is a hot dog, like so:
const food = getFoodOrNull()
if (food.isHotDog()) {
console.log('Hot Dog! 🌭')
} else {
console.log('Not hot dog :(')
}
This code works when our getFoodOrNull()
successfully returns a
Food object. But what if null
is returned?
Turns out we get an exception thrown:
TypeError: null is not an object
. This happens because our food
variable is actually null
, and we’re trying to call a function on
it as if it’s an object.
If we wanted to use short circuit evaluation to get around this, we could rely
on JavaScript’s evaluation of null
as falsy when used in conditions,
to rewrite this as:
const food = getFoodOrNull()
if (food && food.isHotDog()) {
console.log('Hot Dog! 🌭')
} else {
console.log('Not hot dog :(')
}
Written this way, the else branch will successfully run, informing us that we unfortunately do not in fact have a hot dog.
2. Performance and resource usage
In this example, imagine a boolean expression in which the program needs to both consult itself, as well as another program on another server. Let’s use someone applying for a loan at a bank. The bank has 3 conditions that need to be met before they’ll loan money to you:
- You need to be 18 or older
- You need to have at least $100 in your account with them
- Your credit score has to at least be 650
We can assume that the first 2 conditions can be checked for locally within the bank, and that the program already has access to that information. To check the third condition however, we need to consult a server from the credit bureau, which involves a network call.
Network calls are typically slower than local server operations. We can write our code in a couple of ways, one of which is to simply not care which of these conditions we check for first:
if (person.isOfAge() && person.getCreditScore() >= 650 && person.hasFunds()) {
console.log('approved!')
} else {
console.log('rejected')
}
If writen like this, time and computing resources will be waseted on fetching credit score data from a different server if it turns out that the person has less than $100 in their account.
To avoid this we can perform our local and less resource intensive checks first,
THEN make the call to the credit bureau server only if our local checks evaluate
to true
:
if (person.isOfAge() && person.hasFunds() && person.getCreditScore() >= 650) {
console.log('approved!')
} else {
console.log('rejected')
}
3. Default/Fallback Values
Sometimes it makes sense to have a fallback value for your variables when
you know that there’s a chance that you may end up with a null
or
otherwise falsy value.
For this example let’s use a video game where the player needs to create a character. One aspect of this process is naming the character, which is optional for the player. We might write the code to look something like this:
const chosenName = getNameField()
const defaultName = 'Bob'
const characterName = chosenName || defaultName
console.log('Hi', characterName + '!')
In this case if the player provides a name, we’ll have a non-empty string and
characterName
will be assigned to it. In case the player decides
not to enter a name, chosenName
will be ''
(the empty string)
which is be falsey, causing the program to move on to use defaultName
instead.
Hopefully this article has helped you and will lead you to start using JavaScript’s short circuit evaluation capabilities in the code that you write!
In Summary
- Short circuit evaluation is when only a part of a boolean expression is evaluated in order to get the result of the entire expression