Nullish coalescing and optional chaining in JavaScript
Nullish coalescing operator
The nullish coalescing operator (??
) is a logical operator that returns the right-side operand when the operand on its left-side either evaluates to null
or undefined.
Unlike to logical OR operator (||
) which returns the right-hand operand if the left is a falsy value, the nullish coalescing operator does not return the right-hand operand for other falsy values like 0
and ''
.
const logical_or_test = 0 || 45;
const nullish_coalescing_test = 0 ?? 45;
console.log(logical_or_test); // 45
console.log(nullish_coalescing_test); // 0
According to the tc39 proposal site, the design decisions made for the operator are:
- The right argument of
??
is evaluated only if needed ("short circuiting").??
has lower precedence than||
.??
cannot immediately contain, or be contained within, an&&
or||
operation.- The right argument is selected if the left argument is
null
orundefined
.
No chaining with AND or OR
Chaining the nullish coalescing operator with logical AND or OR will throw a syntax error. However, wrapping the expression with a logical AND or OR in a pair of parentheses to show precedence is fine.
This throws a syntax error
0 || undefined ?? "a string";
But this is okay, because of the parentheses
(0 || undefined) ?? 'a string';
To know more about nullish coalescing, check out the documentation on MDN.
Optional chaining operator
The optional chaining operator (?.
) is used to access nested properties of an object without having to check each reference for validity
It functions just as the chaining operator (.
) except that it doesn't throw an error when a reference happens to be nullish (null
or undefined
). The expression is short-circuited with a return value of undefined
when the property being accessed is nullish.
Basic usage
Assuming we have an object containing some random properties
const user = {
name: {
firstName: 'James',
lastName: 'carter'
},
age: 24
};
To access the value of a nested property without having to validate.
var hairColor = user.hair?.color;
console.log(hairColor); // undefined
This syntax simplifies the process of accessing properties which may potentially be nullish.
Trying to access the nested color
property would throw an error:
var hairColor = user.hair.color;
console.log(hairColor);
// => Uncaught TypeError: Cannot read property 'color' of undefined
Normally we would need to use the logical AND
operator (&&
) for validation:
var hairColor = user.hair && user.hair.color;
console.log(hairColor); // undefined
We could also use the ternary operator for validation:
var hairColor = user.hair ? user.hair.color : undefined;
console.log(hairColor); // undefined
Optional chaining with function calls
Calling a function that doesn't exist using ?.
would return undefined
. However, if the property name being invoked as a function exists already but not as a function, an error would be thrown.
const user = {
name: {
firstName: 'James',
lastName: 'carter'
},
age: 24
};
// accessing a non-existent method
console.log(user.name?.getInitials?.());
// => undefined
Firstly we check if the property name exists before invoking as a function, that way if the property is nullish, we get undefined
instead of the error undefined is not function
.
If a property name already exists but not as a function, we would get an error:
console.log(user.name?.firstName?.());
// => Error: user.name.firstName is not a function
Check out the docs on MDN to read more on optional chaining.