Short-Circuiting: And, Or, Nullish Coalescing and Optional Chaining

Pranav PataniPranav Patani
8 min read

The && and || operators

In javascript, the && (and) operator and the || (or) operator are among the initial fundamentals we encounter while learning the language. These are also known as logical operators as they help our program decide in which direction to flow.

The and operator returns true only when both the conditions are met and the or operator returns true even if just one condition is met. Otherwise, they return false.

true || true -> true
false || true -> true
false || false -> false
true && true -> true
false && true -> false
false && false -> false

Apart from returning just the boolean values, these logical operators can also help us achieve short-circuiting.

Short-Circuiting

Short-circuiting is a term used for terminating a piece of the program when a condition is met and no further conditions in that program can affect the outcome of the condition met.

Short-Circuiting using the || operator

The || operator reads the code from left to right and searches for a truthy value. It will return the very first truthy value it finds and if no truthy value is found, then it will return the last falsy value it encountered.

Falsy values: undefined, null, 0, "", false, NaN

Truthy values: Rest all other remaining values.

Let's look at the example below and understand the concept through it.

/*1*/ 5 || 2  //output -> 5
/*2*/ 0 || 2 //output -> 2
/*3*/ null || false //output -> false
/*4*/ `` || `hello` //output-> hello

First example: The or operator short circuits the program as soon as it encounters the first truthy value (5) and returns 5, without looking further for any other value.

Second Example: 0 is a falsy value and hence it further investigates the second value which is a truthy value (2) and therefore returns 2.

Third example: null is a falsy value and hence it further investigates the second value which is again a falsy value(false). There are no more values left to investigate and therefore it returns the last flasy value it encountered which is false .

Fourth Example: The first value is an empty string which is a falsy value and hence it further investigates the second value which is a string hello and therefore is considered a truthy value and the operator returns the string hello.

To understand the concept better, think of it like this, the or operator returns true when one of the given conditions is true. This means even if the other conditions are false, it will return true. Therefore it returns the very first truthy value it encounters.

Short-Circuiting using the && operator

The && operator works just opposite from the || operator. It returns the very first falsy value it encounters and if all the values are truthy, it returns the last truthy value it encountered.

Let's look at the example below and understand the concept through it.

/*1*/ 5 && 2  //output -> 2
/*2*/ 0 && 2 //output -> 0
/*3*/ null && false //output -> null
/*4*/ `hello` && undefined //output-> undefined

First example: The and operator investigates the first value (5) which is a truthy value and hence further investigates the second value (2) which is again a truthy value. There are no more values left to investigate and therefore it returns the last truthy value it encountered which was 2.

Second Example: 0 is a falsy value and hence it short-circuits the execution as it returns the very first falsy value it encounters and therefore returns 0.

Third example: null is a falsy value and hence it again short-circuits the execution and returns null.

Fourth Example: The first value is a truthy value (hello) and hence it further investigates the second value which is a falsy value(undefined) and therefore returns undefined .

To understand the concept better, think of it like this, the and operator returns true only when all the given conditions are true otherwise it returns false. This means even if one of the conditions is false, it will return false. Therefore it returns the very first falsy value it encounters.

Nullish Coalescing Operator And Short-Circuiting

The ?? operator, also known as the Nullish Coalescing operator works very similarly to the or operator but has a slight difference. It returns false for only two of the falsy values - undefined and null . For all other values, it will return true.

Let's look at an example below to understand the difference better.

//First case
0 || 1 //output-> 1
0 ?? 1 //output-> 0
//Second case
null || 1 //output-> 1
null ?? 1 //output-> 1
//Third case
false || true -> true
false ?? true -> false
//Fourth case
undefined || `Hello` //Output-> Hello
undefined ?? `Hello` //Output-> Hello

First case: The || operator returns 1 as 0 is a falsy value and it returns the first truthy value it encounters.

The ?? operator also returns the first truthy value it encounters. But, for this operator, 0 returns true and hence it returns 0, short-circuiting the execution of the further program.

Second case: This time, both the operators returns 1 because both of them identifies null as false and hence they further investigate the second value(1) which is a truthy value and hence returns 1.

Third case: The || operator returns true because false is a falsy value. But the ?? operator returns false even though it is a falsy value because it only considers null and undefined as false values and therefore returns false by considering it a true value.

Fourth case: Both operators return Hello because they both consider undefined as false and therefore investigates the second value (hello) which is a truthy value and hence returns hello .

Optional Chaining (?.)

Optional chaining also short-circuits the further execution of a piece of code but its use is related to objects. We use optional chaining while accessing a property of some object that we are not sure exists.

In general, when we access a property of an object using the dot notation and that property is not existing, it returns undefined . But if we access the property of a non-existing property of an object, we will get an error.

Let's look at an example.

const snacks = {
    chocolates: [`Snickers`, `Lindt Bar`, `Cadbury Dairy Milk`],
    chips: [`Lays`, `Cheetos`, `Tagz`]
}
console.log(snacks.drinks);
//Output
undefined

Here, when we try to access the property drinks of the object snacks we get undefined as the output because that property does not exist.

console.log(snacks.drinks.cold);
//Output
`Uncaught TypeError: Cannot read properties of undefined (reading 'cold')`

But when we try to access the property cold of the property drinks that is already not existing, we get a type error.

This is because javascript considered that non-existing property (drinks) to be undefined. And then we tried to access a property of undefined which is not possible and hence we end up getting an error.

Now, imagine if we were trying to access some data from some server using some API. We are not sure if a property is existing on that server, in this case, if the property is not existing and we try to access it, we may end up getting an error and our program will not run. Therefore, we apply the concept of optional chaining here.

Short-circuiting using the ?. operator

We can short-circuit a program using optional chaining so whenever a property is undefined and we are further accessing the property of the undefined property in our code, the ?. operator will short-circuit the program at the point where the property was considered undefined and return undefined as the output instead of throwing an error.

Consider the example below for a better understanding.

const snacks = {
    chocolates: [`Snickers`, `Lindt Bar`, `Cadbury Dairy Milk`],
    chips: [`Lays`, `Cheetos`, `Tagz`]
}
console.log(snacks.drinks);
//Output
undefined
console.log(snacks.drinks.cold);
//Output
`Uncaught TypeError: Cannot read properties of undefined (reading 'cold')`

//Using Optional Chaining
console.log(snacks.drinks?.cold);
//Output
undefined

As you can observe, we used an ? after the property drinks in the above code and instead of an error, we got undefied as the output. This is because we used the optional chaining operator on the property we were not sure about the existence of.

Hence, as soon as that property was considered undefined, our program short-circuited and did not access further properties of that undefined property and the result was undefined .

Although, if drinks were an existing property, our program would execute normally.

const snacks = {
    chocolates: [`Snickers`, `Lindt Bar`, `Cadbury Dairy Milk`],
    chips: [`Lays`, `Cheetos`, `Tagz`],
    drinks: {
        hot: [`chocolate milk`, `vanilla milk`],
        cold: [`coke`, `fanta`]
    }
}

//Using Optional Chaining
console.log(snacks.drinks?.cold);
//Output
['coke', 'fanta']

Using Optional Chaining And Nullish Coalescing Together

We can combine optional chaining and the nullish coalescing operator together so that whenever we get undefined through optional chaining, we can assign another piece of code to be executed in that case.

Look at the example below.

const snacks = {
    chocolates: [`Snickers`, `Lindt Bar`, `Cadbury Dairy Milk`],
    chips: [`Lays`, `Cheetos`, `Tagz`]
}


//Using Optional Chaining and Nullish Coalescing Together
console.log(snacks.drinks?.cold ?? `There are no drinks :(`);
//Output
`There are no drinks :(`

Here, the optional chaining returns undefined and the nullish coalescing operator then considers it as a false value and investigates the second value which is a string and hence returns the string There are no drinks :( .

Summary

Let us summarise what we have learned in this blog.

First, we understood that short-circuiting is the process of terminating a program once a condition is met and no further conditions can change the program's outcome.

Then we learned about types of operators that can perform short-circuiting.

The or(||) operator: Returns the first truthy it encounters otherwise returns the last falsy value it encountered.

The and(&&) operator: Returns the first falsy it encounters otherwise returns the last truthy value it encountered.

The Nullish Coalescing(??) operator: Works similar to the or operator but returns false only for undefined and null values.

Optional Chaining(?.): Works with objects and is used when we are not sure about the existence of a property. When the property, on which the operator was used, is not existing, optional chaining returns undefined by short-circuiting the piece of code. We can use a nullish coalescing operator with optional chaining to return another value in case optional chaining short-circuits the program.

0
Subscribe to my newsletter

Read articles from Pranav Patani directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pranav Patani
Pranav Patani