Optional Chaining

By  on  

For all of the improvements that the JavaScript language has added over the past few years, like the spread operator, default argument values, and arrow functions, there are still a few features I'd love to see implemented. One such feature is optional chaining. Optional chaining allows developers to reference object properties which may or may not exist without trigger an error.

Take the following example case:

const person = {
  name: "David",
  skills: {
    javascript: {
      frameworks: ["MooTools", "React"],
    }
  },
  save: () => { }
};

// Property that *doesn't* exist (css)
person.skills.css.frameworks;
// Uncaught TypeError: Cannot read property 'frameworks' of undefined

Attempting to get a property of an undefined parent results in a TypeError which can brick your application. In this case we'd want to check to ensure that css property exists:

if(
  person.skills && 
  person.skills.css && 
  person.skills.css.frameworks) {
    // ...
}

I wrote a get and set utility called Objectifier to make referencing nested object properties easier, but with the Optional Chaining proposal, we now have a native way.

A simple example of optional chaining is:

const skills = person?.skills;

You can continue the pattern down the line of nested objects:

const frameworks = person?.skills?.javascript?.frameworks;

If ever a property doesn't exist, the chaining stops and undefined is returned. Optional chaining also supports bracket syntax:

const language = "javascript";
const frameworks = person?.skills?.[language]?.frameworks;

You can also call a function without penalty:

// Calls save if exists, otherwise nothing
const frameworks = person?.save();

You can even use the chaining syntax on the top level object:

addEventListener?.("click", e => { });

methodDoesntExist?.(); // undefined

You can even use destructuring with optional chaining:

const { frameworks, doesntExist } = person.skills?.javascript;

If you want to set a fallback value in the case that a value is undefined, you can do so with ??:

let frameworkz = person?.skills?.["javascript"]?.frameworkz ?? "react.js";

At the time of writing, optional chaining doesn't appear in any browsers yet, but you can play around with optional chaining at the Babel online compiler.

Optional chaining seems like a somewhat controversial change. It's been argued that developers should know and validate the objects they're using; on the other hand, the continuous nested property checking is a nightmare. I look forward to optional chaining in JavaScript. What are your thoughts?

Recent Features

  • By
    Creating Scrolling Parallax Effects with CSS

    Introduction For quite a long time now websites with the so called "parallax" effect have been really popular. In case you have not heard of this effect, it basically includes different layers of images that are moving in different directions or with different speed. This leads to a...

  • By
    Write Better JavaScript with Promises

    You've probably heard the talk around the water cooler about how promises are the future. All of the cool kids are using them, but you don't see what makes them so special. Can't you just use a callback? What's the big deal? In this article, we'll...

Incredible Demos

  • By
    Create Spinning Rays with CSS3 Animations & JavaScript

    Thomas Fuchs, creator of script2 (scriptaculous' second iteration) and Zepto.js (mobile JavaScript framework), creates outstanding animated elements with JavaScript.  He's a legend in his own right, and for good reason:  his work has helped to inspire developers everywhere to drop Flash and opt...

  • By
    Modal-Style Text Selection with Fokus

    Every once in a while I find a tiny JavaScript library that does something very specific, very well.  My latest find, Fokus, is a utility that listens for text selection within the page, and when such an event occurs, shows a beautiful modal dialog in...

Discussion

  1. Micha

    “It’s been argued that developers should know and validate the objects they’re using”

    This will still be the case. Of course if devs don’t make it a habit to always make everything optional just in case. :)

  2. I love optional chaining in C# and use it so often that I feel limited without in when I switch to writing JS. I would love to avoid writing those switch statements to null check an objects hierarchy down to the prop I need. Nice post!

  3. Amazingly well explained, thank you very much !

  4. hacksForHarambe

    it’s going to be a dream come true. es2020 let’s go

  5. toblerone

    “It’s been argued that developers should know and validate the objects they’re using”

    This is pedantic non-sense, it’s has always existed, and will continue to exist, in every possible nook and cranny and has always been, and will continue to be, ignored in the real world.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!