Short Circuiting in JavaScript
Introduction
Consider the following code snippet:
// if-else statement
if (isUserLoggedIn) {
return privateData;
}
else {
return false;
}
The above code can be written in a more concise way like this:
// Short Circuiting
isUserLoggedIn && privateData;
This is an example of short-circuiting and it makes our code more concise.
Short-Circuiting: How the evaluation is done by JavaScript?
We use the &&
and ||
operators to achieve short-circuiting in JavaScript.
When these operators are used, the expression on the left-hand side is evaluated first. If the result of the left-hand side expression is sufficient to determine the overall result of the operation, the right-hand side expression is not evaluated.
💡 Short-circuiting expressions are evaluated from left to right
Short-Circuiting using the &&
operator
A short-circuiting expression using the &&
operator will return either the first falsy operand or the last operand.
const countryName = "India"; // truthy
const countryPopulation = "1.4 Billion" // truthy
const countryRanking = 106; // truthy
const countryWorldCupAppearances = 0; // falsy
const countryWorldCupTitles = ""; // falsy
// AND (&&) operator with no falsy operands (returns the last operand)
console.log(countryName && countryPopulation && countryRanking);
// Output: 106
// AND (&&) operator with truthy and falsy operands (returns the first falsy operand)
console.log(countryRanking && countryWorldCupTitles && countryName);
// Output: ""
Short-Circuiting using the ||
operator
A short-circuiting expression using ||
operator will return either the first truthy operand or the last operand.
const countryName = "India"; // truthy
const countryPopulation = "1.4 Billion" // truthy
const countryRanking = 106; // truthy
const countryWorldCupAppearances = 0; // falsy
const countryWorldCupTitles = ""; // falsy
// OR (||) operator with no truthy operands (returns the last operand)
console.log(countryWorldCupTitles || countryWorldCupAppearances);
// Output: 0
// OR (||) operator with truthy and falsy operands (returns the first truthy operand)
console.log(countryWorldCupTitles || countryName || countryPopulation);
// Output: "India"
A problem with short-circuiting using the ||
operator
Consider the following code snippet:
const setQuantityPerPacket = (item, quantity) => item.qty = quantity || 7;
Here we have used short-circuiting with the ||
operator to set a default value for item.qty
in case the quantity
parameter isn’t passed to setQuantityPerPacket
function.
Let’s see this with an example:
// When item and qty is passed to the setQuantityPerPacket function
const apple = {
itemType: "fruit",
pricePerKg: 130,
}
setQuantityPerPacket(apple, 4);
console.log(apple.qty);
// Output: 4
// When only item and no quantity value is passed to the setQuantityPerPacket function
const orange = {
itemType: "fruit",
pricePerKg: 60,
}
setQuantityPerPacket(orange); // no quantity value passed as second argument
console.log(orange.qty);
// Output: 7
// i.e, the default value we gave using short circuiting
So in the above example, everything is working fine.
So then what is the problem?
The problem arises when we want to specify 0 as the number of items per packet (0 as the quantity per packet seems weird, right? 🙃)
const brinjal = {
itemType: "vegetable",
pricePerKg: 40,
}
setQuantityPerPacket(brinjal, 0);
console.log(brinjal.qty);
// Output: 7
// We wanted 0 to be the output, but who invited 7 here?!
So how did this happen?
Why is 7 the output? We wanted 7 to be item.qty
only if the second argument is not passed to the function. But here we have passed 0 as the second argument, right?
Why is 0 not the output?
And the answer to all these questions is that 0 is a falsy value just like undefined
and so the ||
operator moved on to the next operand in search of a truthy value instead of short-circuiting.
Let’s look at the definition of setQuantityPerPacket
function again:
const setQuantityPerPacket = (item, quantity) => item.qty = quantity || 7;
So if we pass 0 as the second argument to the function, it will return the result of the following expression:
0 || 7
// OR operator will short circuit as soon as it sees a truthy value
// But 0 isn't truthy and so it moved on to 7 and returns it
But we just wanted the default value to be used if the quantity is undefined
, right?
But unfortunately the ||
operator can’t differentiate between undefined
and 0.
So what’s the solution to this problem?
The solution: Nullish Coalescing Operator ( ??
)
I was overwhelmed when I first saw this name - Don't be like me 🙆
Nullish Coalescing Operator is just another logical operator like the AND and OR operators.
💡 When used in a short-circuiting expression, the
??
operator returns the first non-nullish operand or the last operand.
So what are nullish values?
Just like we have truthy and falsy values, we have nullish values in JavaScript.
The nullish values in JavaScript are null
and undefined
. Every other value is a non-nullish value in JavaScript.
Falsy Values | Nullish Values | Truthy Values |
false , "" (empty string), null , undefined , NaN | null , undefined | All values that are not falsy |
So though the ||
operator couldn't distinguish between undefined
and 0, we now have the ??
operator that could.
So let's use it to rewrite setQuantityPerPacket
function to solve the problem we faced before:
const setQuantityPerPacket = (item, quantity) => item.qty = quantity ?? 7;
So now if we pass the quantity value as 0, it will indeed be set to 0 and not 7.
setQuantityPerPacket (brinjal, 0);
console.log(brinjal.qty)
// Output: 0
Conclusion
Short-circuiting is an awesome technique in JavaScript that will help us write concise and expressive code that avoids unnecessary computations. It is a valuable tool for developers to have in their toolkits.
Subscribe to my newsletter
Read articles from Vishnu V Nair directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by