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 attempting 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, it will access property 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: 'Juan',
  address: 'A beautiful house'
};

let postalCode = user?.address?.postalCode;
let barcode = 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 beautiful 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?.subsubproperty;

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.

Usage 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, it would not attempt to invoke the method 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'

Combination 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 error-prone. 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 generate an error

Does Not Detect All Errors

Optional chaining only avoids 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, if calling method() causes your program to crash, ?. does not protect you from that (it does not handle exceptions, it’s not a try-catch).