Mastering JavaScript: optional chaining and nullish coalescing
Tags: javascript
Published: 2023-03-15 00:58:17

by [Sarah Okolo](https://blog.openreplay.com/authors/sarah-okolo)


JavaScript is a popular programming language widely used in web development, and it empowers developers to build complex and interactive applications. As with any language, there are always new techniques and features that developers can learn and master to improve their skills and productivity.


Among these advanced JavaScript techniques are [Optional Chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) and [Nullish Coalescing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing). These features were introduced in [ECMAScript 2020 (ES2020)](https://262.ecma-international.org/11.0/) and they provide a clear and concise way to access and manipulate values within `objects` and `arrays`.

They also help to minimize the amount of code required to handle `null` and `undefined` values, which can often lead to errors and bugs in JavaScript applications.

In this article, we will explore Optional Chaining and Nullish Coalescing in detail and learn how to use these techniques to write more efficient and reliable code in JavaScript. We will also look at some practical examples of how these features can be used in real-world scenarios.


## Optional Chaining: what it is and how it works

Optional Chaining is a feature in JavaScript that allows developers to safely access the properties of an object without having to manually check if the object is `null` or `undefined`. This can be particularly useful when working with complex, nested objects.

The symbol used to denote Optional Chaining in JavaScript is the ` ?.` (question mark followed by a period).

Prior to Optional Chaining, developers often had to use the [ ` && ` (logical AND)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND)operator to check if an object was `null` or `undefined` before accessing its properties. For example, consider the following code:

```javascript
let obj = {
  a: {
    b: {
      c: 'hello'
    }
  }
};

let value;
if (obj && obj.a && obj.a.b && obj.a.b.c) {
  value = obj.a.b.c;
}
```

This code checks if `obj` is defined and not `null`, and if it is, it checks if `obj.a` is defined and not null, and so on. If any of these checks fail, the `value` variable will not be assigned a value.

With Optional Chaining, we can rewrite the above code as follows:

```javascript
let value = obj?.a?.b?.c;
```

This syntax works by first checking if `obj` is defined and not `null`. If it is, it accesses the `a` property of ` obj `. If `obj.a` is defined and not `null`, it accesses the `b` property of ` obj.a`. If `obj.a.b` is defined and not `null`, it accesses the `c` property of `obj.a.b`. If any of these checks fail, the whole expression returns `undefined` without throwing an error.

Optional Chaining can also be used to call functions.
For example:

```javascript
const person = {
  name: 'Jane',
  age: 30,
  car: {
    make: 'Toyota',
    model: 'Camry',
    getInfo: function() {
      return `${this.make} ${this.model}`;
    }
  }
};

const carInfo = person?.car?.getInfo(); 
console.log(carInfo); // "Toyota Camry"
```

In this example, the `person` object has a `car`  property, an object with a `getInfo` method that returns a string with the car's make and model. We can use the Optional Chaining operator ` (?.) ` to access the `car` property and then call the `getInfo` method. If the `person` object or `car` property is `undefined`, the expression will return `undefined`, and no error will be thrown.

Optional Chaining is a handy feature that can help simplify and improve the readability of your code. It is supported in modern browsers and can also be used with transpilers such as Babel](https://babeljs.io/) to provide support in older browsers.

## Understanding nullish coalescing in JavaScript

JavaScript has two types of `null` values: `null` and `undefined`. `null` represents an intentional absence of a value, while `undefined` represents an uninitialized or missing value. Sometimes, you might want to use a default value if a variable is either `null` or `undefined`. This is where 'Nullish Coalescing' comes in.

Nullish Coalescing is a feature in JavaScript that allows you to check if a value is `null` or `undefined`; if it is, use a default value instead.

The symbol used to denote Nullish Coalescing in JavaScript is the ` ?? ` (double question mark).

This operator checks if the value on the left side is `null` or `undefined`. If it is, it returns the value on the right side; otherwise, it returns the value on the left side. It is very useful when you want to check if a variable has a value and provide a default value. It also helps eliminate the need for multiple lines of code that would have been used to check for `null` or `undefined` values, thereby making it more readable and clean.

Let's take a look at a little example:

```javascript
const name = null;
const defaultName = 'John Doe';

const displayName = name ?? defaultName;

console.log(displayName); // Output: "John Doe"
```

In this example, the `displayName` variable is assigned the value of `defaultName` because the `name` variable is `null`. If the `name` variable had been `undefined`, the `displayName` variable would also have been assigned the value of `defaultName`.

One thing to note is that the Nullish Coalescing operator only considers `null` and `undefined` as falsy values. All other values, including empty `strings` and the number ` 0 `, will be considered truthy. 
Here's an example to illustrate this:

```javascript
const count = 0;
const defaultCount = 10;

const displayCount = count ?? defaultCount;

console.log(displayCount); // Output: 0
```

In this example, the `displayCount` variable is assigned the value of `count`, ` 0 `, because the Nullish Coalescing operator(` ?? `) only considers `null` and `undefined` as falsy values. 

The `displayCount` variable would have been assigned the value of `defaultCount` if we had used the [ logical OR operator ` (||) ` ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR), this is because when using this operator, ` 0 ` is always considered as a falsy value.

The Nullish Coalescing operator also can be helpful in situations where you want to use a default value if a variable is `null` or `undefined`, but you don't want to use the default value if the variable is an empty `string` or the number ` 0 `.

Here's an example of how you can use the Nullish Coalescing operator with a function argument:

```javascript
function getUserName(user) {
  const name = user?.name ?? 'John Doe';
  return name;
}

const user1 = { name: 'Jane Doe' };
console.log(getUserName(user1)); // Output: "Jane Doe"

const user2 = {};
console.log(getUserName(user2)); // Output: "John Doe"

const user3 = null;
console.log(getUserName(user3)); // Output: "John Doe"

const user4 = undefined;
console.log(getUserName(user4)); // Output: "John Doe"
```

In this example, the `getUserName` function takes an `object` as an `argument` and returns the name property of the `object` if it exists. If the name property is `null` or `undefined`, the Optional Chaining operator( ` ?. `) will return `null` or `undefined`, and the Nullish Coalescing operator (` ?? `) will use the default value of 'John Doe'.

The `getUserName` function is then called with four different arguments:

- `user1`, which has a name property with a value of 'Jane Doe'
- `user2`, which is an empty `object` and therefore does not have a `name` property
- `user3`, which is `null`
- `user4`, which is `undefined`

For `user1`, the function returns the value of the `name` property, 'Jane Doe'.
For `user2`, the function returns the default value of 'John Doe' because the `name` property is not defined.
For `user3` and `user4`, the function also returns the default value of 'John Doe' because the `user` argument is `null` or `undefined`.



<h2>Session Replay for Developers</h2> 
<p><em>
Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data
</em></p>
<img alt="OpenReplay" width="768" height="400" src="https://blog.openreplay.com/assets/overview_Z17Qdyg.png" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em>




## Use Cases for Optional Chaining and Nullish  Coalescing

Let us dive deeply into a few practical applications of Optional Chaining and Nullish Coalescing in the real world and see how they can solve problems and improve code efficiency across various industries.

### Use Case 1: Deal with missing values

Let's say we have an e-commerce website that displays a user's order history.

The feature would allow users to view their past orders, including information about the products they purchased, the date of purchase, and the order total.

The data for the orders are stored in a JavaScript object that looks something like this:

```javascript
const orders = [
  {
    id: 1,
    date: "2022-01-01",
    items: [
      {
        product: {
          name: "Shirt",
          price: 30
        },
        quantity: 2
      },
      {
        product: {
          name: "Pants",
          price: 50
        },
        quantity: 1
      }
    ],
    shipping: {
      name: "John Smith",
      address: {
        street: "123 Main St",
        city: "Springfield",
        state: "Oregon",
        zip: "97477"
      }
    }
  },
  {
    id: 2,
    date: "2022-02-01",
    items: [
      {
        product: {
          name: "Shoes",
          price: 100
        },
        quantity: 1
      }
    ],
    shipping: {
      name: "Jane Doe",
      address: {
        street: "456 Elm St",
        city: "Springfield",
        state: "Oregon",
        zip: "97477"
      }
    }
  }
];
```

To display the order history, we can loop through the `orders` array and use optional chaining to access the `properties` of each order. For example, to display the name of the product and its quantity, we can use the following code:

```javascript
orders.forEach(order => {
  order.items.forEach(item => {
    const productName = item.product?.name;
    const productQuantity = item.quantity;
    console.log(`Product: ${productName}, Quantity: ${productQuantity}`);
  });
});
```

If the `item` object does not have a product property, ` item.product?.name ` will return `undefined`, and the code will not throw an error.

Also, to display the shipping address of an order, we can use the following code:

```javascript
const shippingAddress = order.shipping?.address?.street ?? 'N/A';
console.log(`Shipping Address: ${shippingAddress}`);
```

If the `order` object does not have a shipping property, ` order.shipping?.address?.street ` will return `undefined` and ` ?? 'N/A' ` will assign the value ` N/A `to the `shippingAddress` variable, thus preventing the code from throwing an error.

This way, we can use Optional Chaining and Nullish Coalescing to provide default values if a property is `null` or `undefined`.


### Use case 2: Access deeply nested object properties

Suppose you have an object representing a customer record with nested properties for the customer's name, address, and phone number. The object might look like this:

```javascript
const customer = {
  name: {
    first: 'John',
    last: 'Doe'
  },
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY',
    zip: 10001
  },
  phone: '212-555-1212'
};
```

If you want to access the customer's phone number, you can simply use dot notation:

```javascript
const phone = customer.phone;  // returns '212-555-1212'
```

But if you want to access a nested property that might be `null` or `undefined`, you can use Optional Chaining to safely access the property without causing an error:

```javascript
const phone = customer.phone;
const zip = customer.address?.zip;  // returns 10001
``` 

Without Optional Chaining, you would have to check whether the address property is truthy before attempting to access the `zip` property:

```javascript
const phone = customer.phone;
const zip = customer.address && customer.address.zip;  // returns 10001
```

### Use case 3: Provide default values

Another example of using Optional Chaining and Nullish Coalescing in a JavaScript application could be a social media platform feature allowing users to view and edit their profile information.

The data for the user's profile is stored in a JavaScript object that looks something like this:

```javascript
const user = {
  id: 1,
  name: "John Smith",
  email: "john.smith@example.com",
  bio: "Software developer and avid traveler",
  social: {
    facebook: "john.smith",
    twitter: "jsmith",
    website: "https://johnsmith.com"
  },
  preferences: {
    theme: "dark",
    notifications: true
  }
};
```
To display the user's social media links on their profile, we can use Optional Chaining to access the properties of the social object. For example, to display the user's Facebook and Twitter links, we can use the following code:

```javascript
const facebookLink = user.social?.facebook ?? "Add Facebook link";
const twitterLink = user.social?.twitter ?? "Add Twitter link";
console.log(`Facebook: ${facebookLink}`);
console.log(`Twitter: ${twitterLink}`);
```

Here, if the `user` object does not have a social property or if it doesn't have a Facebook or Twitter property, `user.social?.facebook` or `user.social?.twitter` will return `undefined` and `?? "Add Facebook link"` or `?? "Add Twitter link"`will assign the default value to the variable, thus preventing the code from throwing an error.

To allow users to edit their profile information, we can use Nullish Coalescing to provide default values when updating the user's preferences. For example, to update the user's theme and notifications preferences, we can use the following code:

```javascript
function updatePreferences(user, { theme = user.preferences.theme, notifications = user.preferences.notifications } = {}) {
  user.preferences.theme = theme ?? user.preferences.theme;
  user.preferences.notifications = notifications ?? user.preferences.notifications;
}
```
Here, if the theme or notifications values passed to the function are `null` or `undefined`, ` ?? user.preferences.theme ` or ` ?? user.preferences.notifications` will keep the previous value of the theme or notifications and prevent the code from assigning `null` or `undefined` to the user's preferences.

In this way, we can use Optional Chaining to safely access properties of nested objects and  Nullish Coalescing to provide default values when updating data in the application.


## Tips for effective use of optional chaining and nullish coalescing

Optional Chaining and Nullish Coalescing can be very useful when working with complex nested objects and data structures. Still, they also have their own quirks and edge cases of which we should be aware before using them. Let's take a look at some:

- Be aware that the Optional Chaining operator ` (?.) ` only works with `objects` and will not work with primitive values such as `numbers`, `strings`, or `booleans`. If you try to use it with a primitive value, you will get a `TypeError`.
Here is an example:
```javascript
let person = { name: "John", age: 25 };
console.log(person?.name.toUpperCase()); // "JOHN"

let age = "Not specified";
console.log(person?.age.toString()); // TypeError: Cannot read property 'toString' of undefined
```
In the above example, using the Optional Chaining operator to access the `name` property of the `person` object works as expected, but trying to use it to access the `age` property of a string variable throws a `TypeError`.

- You can also use optional chaining in combination with the [`destructuring assignment`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) to extract multiple properties from an object in a concise and readable way. For example, instead of writing
```javascript
let street = user?.address?.street;
let city = user?.address?.city;
```
You could use the following:

```javascript
let { street, city } = user?.address || {};
```

- When using the Optional Chaining operator on a function call, be aware that if the function returns `null` or `undefined`, the entire expression will also evaluate to `null` or `undefined`. So it's important to check the return value of the function.
```javascript
let user = { name: "John", age: 25 };
let getAge = () => user.age;
console.log(user?.getAge()); // 25

let getAddress = () => null;
console.log(user?.getAddress()); // null
```
In the first example, the function `getAge` returns the value of `user.age`, so the Optional Chaining operator works as expected. But in the second example, the function `getAddress` returns `null`, so the Optional Chaining operator also evaluates to `null`.

- Understand that when using the Nullish Coalescing operator ` (??) ` with falsy values. The operator only returns the default value when the variable is `null` or `undefined`, not when it’s "falsy" (false, 0, `""`, etc.). In such cases, you should use a [Conditional Ternary Operator `? :`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) instead.
For example:

```javascript
let user = { name: "John", age: 0 };
console.log(user?.age ?? 25); // 0
console.log(user?.address ?? "Not specified"); // "Not specified"
```
In this example, the `age` is falsy but not `null` or `undefined`, so the ` ?? ` operator will not work and will return the value of `user.age`. But in the case of `user.address`, either `null` or `undefined`, the ` ?? ` operator will return the default value `Not specified`.

- When using the Nullish Coalescing operator with objects, be careful when the default value is also an object because JavaScript objects are compared by reference, not by value.
```javascript
let user = { name: "John", age: 25 };
let defaultAddress = { street: "Unknown", city: "Unknown" };
console.log(user.address ?? defaultAddress); // { street: "Unknown", city: "Unknown" }

user.address = defaultAddress;
console.log(user.address ?? { street: "Unknown", city: "Unknown" }); // { street: "Unknown", city: "Unknown" }
```

In the first example, the default value is assigned to `user.address`, but in the second example, the default value is not assigned because it's the same object as the one in `user.address`, so the ` ?? ` operator returns the same object.

- Use Nullish Coalescing when you want to provide a default value for a variable if it is `null` or `undefined`. This allows you to avoid having to use the ternary operator ` ? : ` or a default parameter in a function.
For example:

```javascript
const obj = {
  foo: undefined
};

// Without nullish coalescing
const value = obj.foo !== null && obj.foo !== undefined ? obj.foo : 'default value';

// With nullish coalescing
const value = obj.foo ?? 'default value';
```



- Always be mindful of the order of precedence of the operators. In javascript, the `?.` operator has higher precedence than the `?? ` operator. So `let name = person?.name ?? 'John Doe'` will check for `person.name` first, and if it's `null` or `undefined`, it will check for the default value.

So that your code behaves as expected and avoids any potential errors, It's very important to be mindful of these when using optional chaining and nullish coalescing in JavaScript because they can lead to unexpected results if not used correctly.


## Conclusion

In conclusion, mastering advanced JavaScript techniques such as Optional Chaining and Nullish Coalescing can greatly improve the clarity and simplicity of your code. Optional Chaining allows for concise handling of potentially `null` or `undefined` values, while nullish coalescing allows for a default value to be assigned in the case of `null` or `undefined`. These techniques have various use cases and can be effectively utilized with a bit of practice and careful consideration. Using Optional Chaining and Nullish Coalescing, developers can write more efficient, clean, and maintainable code.

Also, as these are both relatively new features in JavaScript, they may not be fully supported in all browsers. It's always a good idea to check the current browser support for new features before using them in production code. You can use a tool like [caniuse.com](https://caniuse.com/mdn-javascript_operators_optional_chaining) or check the browser's developer documentation for more information.

I hope this article brought clear light to these topics, and as always, Happy Coding.





[![newsletter](https://blog.openreplay.com/newsletter_Z1P0UIP.png)](https://newsletter.openreplay.com/)