Javascript Optional Chaining Operator
Introduction
Learning the optional chaining syntax allows us to safely access properties of nested objects without causing errors, even if those properties do not exist.
The Problem of “Non-existent Properties”
Accessing object properties is a very intuitive task that developers do every day. However, when the source of data is unstable, such as when using data from third-party sources or user input, how can we avoid errors caused by using non-existent values?
const person = { name: 'Doe', age: 28,};
console.log(person.child.age); // Uncaught TypeError: person.child is undefined
We can use the conditional operator or the logical operator to achieve this:
// If person.name exists, use person.name, otherwise it equals undefined.console.log(person.name ? person.name : undefined);
// If person exists, get person.name, otherwise it equals undefinedconsole.log(person && person.name);
Although this works, it is not a very elegant solution, and as the level of nesting increases, the code becomes more cumbersome.
const person = {};
console.log(person.address ? (user.address.street ? user.address.street.name : null) : null);
Using Optional Chaining .?
The solution to the above problem is simple: use optional chaining. In short, if the input value does not exist or is null
, the selected value will be treated as undefined
, preventing the program from crashing. There are two usages:
- Avoid crashing the program due to accessing non-existent values (if the value does not exist, it gets
undefined
) - Set default values (in conjunction with the
??
operator)
const person = {};
// Gets undefinedconsole.log(person?.name);
// Gets default value "Unnamed User"console.log(person?.name ?? 'Unnamed User');
This is typically used when accessing remote data or the DOM. If you are very sure that the data you are retrieving will definitely exist, you can omit it; including it adds an extra layer of exception protection.
Additionally, “chaining” optional chaining is also possible, as shown below:
let user = {};
// Gets undefinedconsole.log(user?.address?.street);
Notes
You should not overuse ?.
optional chaining; use it only for non-essential data selection. For example, when the address
in the user
object is non-essential, you can use user.address?.street
to select it, rather than user?.address?.street
.
Excessive use of optional chaining can lead to inappropriate timing warnings being suppressed, causing variables to be filled with undefined
values, making debugging more difficult.