Introduction
Prevention is better than cure! When we stumble on a scenario with a possibility of undefined
or null
, it's better to have a checkpoint than break the code!
We can handle undefined/null in the following way, right?
function printName(name){
if(name === null || name === undefined){
console.log("No name");
}
else {
console.log(name);
}
}
printName(undefined); //No name
printName(null); //No name
function printName(obj){
if(obj.name === null || obj.name === undefined){
console.log("No name");
}
else {
console.log(name);
}
}
printName({name:null}); //No name
printName({name:undefined}); //No name
Aren't these verbose ways of dealing with null or undefined scenarios?
Just imagine if we have a lot of nested objects then the conditions would also increase a lot!
nullish coalescing
One way to overcome the below scenario is by us of nullish coalescing operator.
function printName(name){
return name??"No name";
}
console.log(printName(undefined)); //No name
console.log(printName(null)); //No name
nullish coalescing operator is a logical operator that returns the right-hand side operand when its left-hand side operand is null
or undefined
, and otherwise returns its left-hand side operand.
Syntax
leftOperand ?? rightOperand
First, it checks, if the leftOperand is null/undefined, if it's not then it won't evaluate the rightOperand, otherwise, it returns the rightOperand.
A special case of logical OR
Logical OR returns the right-hand side operand if the left-hand side operand is falsy(you can out the list on MDF for different falsy values)
The difference between logical OR and nullish coalescing is that logical OR would return the right-hand side operand if the left-hand side operand is falsy, unlike nulish coalescing which evaluates the right-hand-side operand only if the left hand operand s null/undefined.
const age=0;
console.log(age||24); //24
const age=0;
console.log(age??24); //0
Another way to go about the null/undefined checks is by the use of logical AND.
function printName(obj){
return obj&&obj.name
}
console.log(printName({name:undefined})); //undefined
console.log(printName({name:null})); //null
However, this again becomes verbose because if we want to return a default value if the value is missing, we need if else
block!
Optional Chaining
Optional chaining is another way to overcome the undefined/null
case in the object by using optional chaining.
If a property or a method is missing in an object and we try to access it, there will be an error thrown. We can use optional changing to evaluate the missing value to undefined
.
Without optional chaining
function printName(obj){
return obj.name;
}
console.log(printName()); //TypeError
With optional chaining
function printName(obj){
return obj?.name;
}
console.log(printName()); //undefined
Syntax
obj.val?.prop
obj.val?.[expr]
obj.func?.(args)
For invoking a method, we can use ?. in invocation to prevent the Type error
nullish coalescing and optional chaining together
const details={
name:"Rajashree",
address:{
city:"Kolkata"
}
}
console.log(details.address?.country??"No country specified");
We can use ?.
to check if the property exists and if it doesn't we print the default value by using ??
Closing thoughts
The optional chaining operator is ideal for null-checking deeply nested objects. It allows us to avoid writing a whole bunch of if statements to check for the existence of the properties.
The nullish coalescing can be used if we want to assign a default value for null/undefined value.
References
https://medium.com/gradeup/optional-chaining-and-nullish-coalescing-as-a-saviour-34a0c024c6b3
https://medium.com/gradeup/optional-chaining-and-nullish-coalescing-as-a-saviour-34a0c024c6b3
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining