Codementor Events

Optional chaining operator - JavaScript

Published Aug 03, 2019Last updated Jan 29, 2020
Optional chaining operator - JavaScript

So it's coming to the web browser; it's close, it allows you to write better code in JavaScript. Not in terms of beauty, but definitely in terms of feeling comfortable in writing conditionals.

Optional chaining operator ladies and gentlemen, I've been waiting for it a long time, since it was announced in Stage 1.

1. Who created the proposal?

This proposal was prepared by Gabriel Isenberg, Claude Pache, and Dustin Savery.

2. Optional chaining's syntax

The first specification of the syntax starts with "?.". That's how you declare optional chaining operator.

Let me show you what you can use it with down below:

2.1 obj?.prop - optional static property access

This one is straightforward, allows you to check if the next static property exists in the main object.

//Instead of writing: 
const patientFirstName = obj.patient && obj.patient.firstname;

//You can write:
const patientFirstName = obj?.patient?.firstname;
2.2 obj?.[expr] - optional dynamic property access

Writing optional chaining in this way, allows us to check dynamically if the property exists in the main object.

const filterDynamicProps = array.filter(property => {
   const isOurPropThere = obj?.[property];
   const isSecondLevelPropThere = obj?.[property]?.[property];
   if(isOurPropThere) {
     return property;
   }
});

2.3 func?.(...args) - optional function or method call

This one is one of my favourites; I like this idea of checking if the function occurs in the code and invoking it at the same time, including a single infinite number of parameters and rest operator.

// Simple function:
function doSomething() {
   return 'Something';
}

doSomething?.() // We're checking if the function is callable and if it exists

// Closure:
function doSomething() {
   return {
      func1: () => {
         return true;
     },
     func2: () => {
        return false;
     }
  }
};

// Looks a bit clunky and complicated at first
// We're checking if "doSomething" is callable and exists
// Secondly, we're checking if it's returned closure function exists and is callable
doSomething?.().func1?.();

3. Everything else you need to know about the syntax

If the operand at the left-hand side of the ?. operator evaluates to undefined or null, the expression evaluates to undefined. Otherwise, the targeted property access, method or function call is triggered normally.

a?.b                          // undefined if `a` is null/undefined, `a.b` otherwise.
a == null ? undefined : a.b

a?.[x]                        // undefined if `a` is null/undefined, `a[x]` otherwise.
a == null ? undefined : a[x]

a?.b()                        // undefined if `a` is null/undefined
a == null ? undefined : a.b() // throws a TypeError if `a.b` is not a function
                              // otherwise, evaluates to `a.b()`

a?.()                        // undefined if `a` is null/undefined
a == null ? undefined : a()  // throws a TypeError if `a` is neither null/undefined, nor a function
                             // invokes the function `a` otherwise

4. What was the motivation behind it?

The primary motivation behind it represents deep objects tree. How many times we had to check it the property contains another property by using long-short circuit conditionals?

Basic example:

const patientFirstName = obj.patient && obj.patient.firstName;

5. What is the support?

Unfortunately - none. The good news is that it is in Stage 3, I suspect that ones it is released, web browser vendors implement it

Although, it is available in Babel 7

6. Resources

If you want to find out more about optional chaining operator, below you can find useful links:

  1. Optional chaining - MDN
  2. TC39 Proposal Docs

This article was initially written on: Robert Wozniak - Dev blog
Thank you for reading, until next time!

Discover and read more posts from Robert Wozniak
get started