How to Use Optional Chaining (?.) in JavaScript

Tuğçe Çifci
6 min readJun 13, 2024

Hello everyone! 👋

✨ In this article, I’ll explore optional chaining through practical examples, demonstrating how it streamlines code and makes development more efficient. JavaScript development often involves navigating through nested objects, which can be cumbersome and error-prone, especially when dealing with null or undefined values. Enter optional chaining—a game-changer in modern JavaScript syntax.

👀 Table Of Contents

1- What is Optional Chaining?

2- Before Optional Chaining

3- After Optional Chaining

4- Optional Chaining with Arrays

5- Optional Chaining with Functions

6- Conclusion

1- What is Optional Chaining?

Optional chaining is a feature introduced in JavaScript with ES2020 (ECMAScript 2020). It provides a concise and safe way to access properties of an object when there is a possibility of encountering undefined or null values along the property chain.

Traditionally, when accessing nested properties of an object, you would need to perform multiple checks to ensure that each property along the chain exists before accessing its value. Optional chaining simplifies this process by allowing you to safely navigate through an object’s properties without explicitly checking for the existence of each property.

If you’ve just started to read the tutorial and learn JavaScript, maybe the problem hasn’t touched you yet, but it’s quite common.

As an example, let’s say we have user objects that hold the information about our users. Most of our users have addresses in user.address property, with the street user.address.street, but some did not provide them. In such case, when we attempt to get user.address.street, and the user happens to be without an address, we get an error:

let user = {}; // a user without "address" property

alert(user.address.street); // Error!

That’s the expected result. JavaScript works like this. As user.address is undefined, an attempt to get user.address.street fails with an error. In many practical cases we’d prefer to get undefined instead of an error here (meaning “no street”).

🦥 So what can we do?

The obvious solution would be to check the value using if or the conditional operator ?, before accessing its property, like this:

let user = {};

alert(user.address ? user.address.street : undefined);

It works, there’s no error… But it’s quite inelegant. As you can see, the "user.address" appears twice in the code.

2- Before Optional Chaining

onst user = {
id: 1,
name: 'Tuğçe',
address: {
city: 'Ankara',
zipcode: '10001'
}
};

// Traditional way of accessing a nested property
const city = user && user.address && user.address.city;

In the above example, if any intermediate property along the chain (user, address, or city) is undefined, the optional chaining (?.) will short-circuit the expression and return undefined, preventing a TypeError from being thrown.

3- After Optional Chaining

const user = {
id: 1,
name: 'Tuğçe',
address: {
city: 'Ankara',
zipcode: '10001'
}
};
// Using optional chaining to access the nested property
const city = user?.address?.city;

Optional chaining makes the code more concise and readable, especially when dealing with deeply nested objects or when accessing properties that may or may not exist. It simplifies error handling and reduces the need for verbose null or undefined checks.

4- Optional Chaining with Arrays

Optional chaining can also be used with arrays in JavaScript, but it’s important to note that optional chaining primarily works with object properties, not array elements. However, you can still use optional chaining in scenarios where you want to access properties of array elements that might be missing or undefined.

🦥 Here’s a basic example demonstrating optional chaining with arrays:

// Define an array of objects with optional properties
const users = [
{ id: 1, name: 'Tuğçe', address: { city: 'Ankara' } },
{ id: 2, name: 'Lily' }
// The third object intentionally does not have the 'address' property
];

// Accessing a nested property of an array element without optional chaining
const city = users[0] && users[0].address && users[0].address.city;

// Accessing a nested property of an array element with optional chaining
const city = users[0]?.address?.city;

console.log(city); // Output: "Ankara"

// Accessing a nested property of a potentially missing array element
const city2 = users[1]?.address?.city;

console.log(city2); // Output: undefined

In this example, users is an array of objects representing users, where some users have an address property and some don't. We want to access the city property nested within the address object of the first user in the array.

With optional chaining, we can directly access the city property of users[0]?.address?.city. If the address property or city property of the first user is missing or undefined, the expression will short-circuit and return undefined without throwing an error.

Similarly, we can use optional chaining to safely access properties of array elements that might be missing or undefined, which can help make our code more concise and readable.

5- Optional Chaining with Functions

Optional chaining with functions allows you to call functions on potentially null or undefined values without causing errors. This feature is particularly useful when working with nested objects or when accessing methods on objects that may or may not exist.

🦥 Here’s a basic example demonstrating optional chaining with functions:

// Define an object with nested optional methods
const person = {
name: 'Tuğçe',
job: {
title: 'Frontend Developer',
sayHello: function() {
console.log(`Hello, my name is ${this.name} and I work as an ${this.title}.`);
}
}
};

// Call a nested method on an object without optional chaining
if (person && person.job && person.job.sayHello) {
person.job.sayHello();
}

// Call a nested method on an object with optional chaining
person?.job?.sayHello?.();

6- Conclusion

Optional chaining in JavaScript provides a concise and safe way to access properties and methods of objects, especially in scenarios where those properties or methods may not exist or may be nested deep within the object structure. It simplifies the code and reduces the need for verbose null or undefined checks, making the code more readable and maintainable.

💡 Key points about optional chaining:

  • Conciseness: Optional chaining allows for cleaner and more concise code by reducing the need for nested if statements or ternary operators to check for null or undefined values before accessing properties or methods.
  • Safety: By using optional chaining, developers can avoid runtime errors caused by attempting to access properties or methods of undefined or null values. Instead of throwing errors, optional chaining expressions short-circuit and return undefined if any part of the chain is null or undefined.
  • Readability: Optional chaining improves code readability by clearly indicating that certain properties or methods are optional and may not always exist. This makes it easier for developers to understand the intent of the code at a glance.
  • Nested Access: Optional chaining can be applied to deeply nested properties or methods, simplifying the process of accessing deeply nested values without having to check each intermediate property or method for existence.
  • Compatibility: Optional chaining is a feature introduced in ECMAScript 2020 (ES2020), so it may not be supported in older browsers or environments. However, its usage is becoming increasingly common as more projects adopt modern JavaScript features.

🦥 In conclusion, optional chaining is a powerful addition to the JavaScript language that simplifies and improves the safety of property and method access in complex object structures, leading to cleaner, safer, and more readable code.

🧐 For any questions, comments, or feedback, feel free to reach out to me. Until the next article, happy coding!

✉️ Click here to contact me.

--

--