Language: EN

javascript-operador-encadenamiento-opcional

Optional Chaining Operator `?.` in JavaScript

The optional chaining operator (?.) allows us to safely access properties and methods of objects when the object that has the property may be null or undefined.

This avoids the need to write multiple conditional checks to ensure that each level of the access chain is defined.

Before the introduction of the optional chaining operator in JavaScript, we had to manually check if each property existed before trying to access the next one.

The ?. operator is very useful and greatly simplifies our code (and you know, simpler is more readable and maintainable).

Basic Syntax

The basic syntax of the optional chaining operator is as follows:

const result = object?.property;

In this case,

  • If object has a defined value, property will be accessed normally.
  • If object is null or undefined, result will be undefined and no error will be thrown.

Let’s look at a practical example to better understand how the optional chaining operator works:

let user = {
  name: 'Luis',
  address: 'A nice house'
};

let postalCode = user?.address?.postalCode;
let postalCode = user?.product?.barcode;
console.log(postalCode); // Result: '12345'

In this example,

  • We access the address property of the user object.
  • Since this property exists, we will get the value ‘A nice house’.

On the other hand,

  • We also access product.barcode (which does not exist)
  • However, instead of throwing an exception, we simply get undefined.

Multiple Chaining

The optional chaining operator can also be used with multiple chaining. This allows us to make safe “chains.”

let result = object?.property1?.subproperty?.othersubproperty;

For example,

const user = {
  profile: {
    address: {
      city: 'Madrid'
    }
  }
};

const city = user.profile?.address?.city;

console.log(city); // 'Madrid'

If user.profile or user.profile.address were null or undefined, city would be undefined, avoiding an error when trying to access a property of an undefined object.

Using with Methods

The optional chaining operator can also be used to invoke methods that might not be defined:

const result = object?.method?.();

Here, if object or method are null or undefined, no error will be thrown and result will be undefined. If both are defined, method will be invoked.

For example

const person = {
  name: 'Ana',
  greet: () => 'Hello'
};

const greeting = person.greet?.();
console.log(greeting); // 'Hello'

If person.greet were null or undefined, the method would not be attempted to be invoked and greeting would be undefined.

Accessing Array Elements

Although less common, the optional chaining operator can also be used to access elements of arrays:

const users = [{ name: 'Carlos' }, null, { name: 'Sofia' }];
const firstName = users[0]?.name;
const secondName = users[1]?.name;
const thirdName = users[2]?.name;

console.log(firstName); // 'Carlos'
console.log(secondName); // undefined
console.log(thirdName); // 'Sofia'

Combining with Nullish Coalescing Operator ??

The optional chaining operator can be combined with the nullish coalescing operator (??) to provide default values:

const user = {};
const name = user.profile?.name ?? 'Default name';
console.log(name); // 'Default name'

Here, name will be 'Default name' if user.profile is undefined or null.

Comparison with Other Access Techniques

Using && Conditions

Before optional chaining, it was common to use && conditions to avoid access errors in nested objects:

const city = user && user.profile && user.profile.address && user.profile.address.city;

This approach is less readable and more prone to errors. The optional chaining operator simplifies this syntax

const city = user?.profile?.address?.city;

Avoid using && for this. It’s terrible. Use ?., that’s what it’s for 😉

Using Ternary Operator

The ternary operator can also be used to check if intermediate levels are defined:

const city = user ? (user.profile ? (user.profile.address ? user.profile.address.city : undefined) : undefined) : undefined;

However, this method no one can read that is more complex and less readable compared to the optional chaining operator.

Don’t do that! 😆

Limitations of the Optional Chaining Operator

Does Not Prevent Assignments

The optional chaining operator cannot be used for assignments. It can only be used to access properties and methods:

object?.property = value; // This will throw an error

Does Not Catch All Errors

Optional chaining only prevents errors related to an undefined property or method. It does not handle other types of errors that may arise when accessing properties or methods:

const result = object?.method()?.property;

That is, obviously, if calling method() causes your program to crash, ?. does not protect you from that (it does not manage exceptions, it is not a try-catch).