Optional chaining is a feature in Javascript which lets us access the child properties of an object, even if the parent object doesn't exist. It's used when properties are on an object, so instead of returning an error, we still get a result from Javascript. optional . Let's look at how it works Introduction to Optionality in Javascript Anyone who has used Javascript for any length of time may have run into a pretty common issue where accessing a child property that is optional requires a lot of additional logic to test it exists before we do anything. As an example, imagine an article building piece of software, where the object may have a child property called , and within that, we may have some basic information on a related article. article relatedArticle Let's imagine we access a related article's URL by - however, not every article will have a related article. Traditionally in Javascript, assuming is defined, we may have written something like this: article.relatedArticle.url article let article = {}; let url; if(article.relatedArticle !== undefined) { url = article.relatedArticle.url; } Or we may be tempted to try something like this instead: let article = {} let url = article.relatedArticle ? article.relatedArticle : undefined; This ultimately avoids the following error, should be undefined: relatedArticle Cannot read properties of undefined (reading 'url') If we have multiple child levels, though, we can end up writing quite a long string of statements. This can get quite tedious and out of control for very big objects. undefined For example, below we try to access when we aren't really sure if these objects will be defined: article.relatedArticle.url.rootDomain let article = {}; let rootDomain; if(article.relatedArticle !== undefined && article.relatedArticle.url !== undefined) { rootDomain = article.relatedArticle.url.rootDomain; } solves this problem of excessive checks. If something is given an optional tag, then if it exists, the value will be returned - otherwise, it will not throw an error. In the above example, we don't even really need an statement, anymore: Optionality undefined ?. if let article = {}; let rootDomain = article.relatedArticle?.url?.rootDomain; By adding , should , or be or , it will simply pass onto the next property without throwing an error. We can even improve this by setting a default value using nullish coalescing. Below, if the property is found to be undefined, it will instead return : ?. relatedArticle url undefined null rootDomain https://google.com/ let article = {}; let rootDomain = article.relatedArticle?.url?.rootDomain ?? 'https://google.com/'; How to use Optional Chaining in Javascript In most examples, you can use optional chaining as described above, to avoid errors on truly optional properties within an object: let article = {}; let rootDomain = article.relatedArticle?.url?.rootDomain; One caveat to this is that you cannot add a question mark to the end of an object. The following, will, therefore, throw an error: let article = {}; let rootDomain = article.relatedArticle?.url?.rootDomain?; // Will throw an error like `Unexpected token ';'` Although this is the most common way to use optional chaining, . Let's explore those too, to see the full extent of how to use optional chaining in your code and projects. there are other ways to implement it in your code When to not use optional chaining You should use optional chaining to simply avoid errors. If you overuse optional chaining, you will silence errors and make it much more difficult to debug your code later. Instead, ! NOT only use optional chaining for REAL optional properties Optional Chaining with Functions You can use optional chaining with functions that you expect may return objects. It works exactly the same as before, only we add after the function - : ?. myFunction(...arguments)?.x let myFunction = (x, y, z) => { if(z !== undefined) { return { x: x, y: y, z: z } } } let arguments = [ 1, 2, 3 ]; let getX = myFunction(...arguments)?.x; console.log(getX); // Returns 1; It's good to know at this stage that by default if a function has no , it returns - so this can be quite useful in situations where you are not sure a function will return anything at all. return undefined Optional Chaining with Arrays Optional chaining can also be used with arrays. For example - if you aren't sure if a property will be defined, but it contains an array. Below, a user can have an array of valid addresses, and we want to get the first line of their address, from their address. Since it may not always exist, we can use optional chaining here to try and recover it. first let myUser = { name: "John Doe", age: 155 } let getAddress = myUser.addresses?.[0]?.first In this case, is not defined on , so will simply return . If we want to check a property that should be array, the notation is , while if we want to check an array index that may not exist, but has child elements within, the notation is . addresses myUser getAddress undefined obj.prop?.[index] obj[index]?.prop Optional Chaining with Optional Functions Sometimes, the return of an object property may be a function. In these cases, we may want to run this function, but since it isn't always defined, we only want it to fire if it's there. In this case, we can use the notation to run the function, should it exist. ?.() Consider the following example: let myObject = [ { id: 15, adder: (x) => { return x + 10; } }, { id: 145, } ] myObject.forEach((item) => { let runFunction = item.adder?.(10) || 10; console.log(runFunction); }); , we have an object which contains an array, where each object contains an id - , and may also contain the function . In this example, we want to run this function if it exists, or default the value to if the function is undefined - so we run the function: Above id adder adder 10 let runFunction = item.adder?.(10) || 10; Here, if is defined, it runs, so we get or , for the first element of the array, and simply for the second, since does not exist. adder x + 10 20 10 adder Conclusion Optional Chaining is incredibly useful and widely supported (excluding Internet Explorer). It can be used with pretty much any combination of property, array, or function, depending on return types. For example: obj?.property obj?.[property] obj[index]?.property obj?.(args) func(args)?.property Optional chaining is therefore a great way to simplify your code and gives syntax and meaning to real optional properties within your objects. Also published . here