Of the various Features proposed in ES2020, perhaps two of the simplest features will prove to be the most useful, at least in terms of simplification and maintenance are concerned.
Specifically, the Optional Chaining Operator and Nullish Coalescing Operator are of particular interest as they are certain to result in less verbose, less error prone expressions.
Optional Chaining
In a nutshell, Optional Chaining provides a syntax for undefined / null
checks when performing nested object references using a simple question mark appended by a dot (?.
) notation.
For instance, consider how many times you may have written defensive expressions similar to the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const roleName = ( user && user.role && user.role.name ); // or provide a default value ... const roleName = ( user && user.role && user.role.name || '' ); // or ... const roleName = ( user && user.role ? user.role.name : '' ); |
Or perhaps you have assigned intermediate values to temporary variables to perform the same:
1 2 3 4 5 | const role = user && user.role; const isAdmin = Boolean(role && role.isAdmin); const roleName = role && role.name; |
The need to check for possible reference errors quickly becomes tedious, and with each lookup we increase the potential for introducing bugs. Utilities can be implemented for delegating these checks, but ultimately, this just moves the problem from one context to another, resulting in additional points for failure.
With Optional Chaining, however, accessing properties safely becomes considerably less verbose, as the examples above can be simplified to:
1 2 3 4 | const isAdmin = Boolean(user?.role?.isAdmin); const roleName = user?.role?.name; |
Reference checks when invoking functions also become simplified:
1 2 3 | const permissions = user?.role?.getPermissions(); |
And dynamic property references can safely be performed as well:
1 2 3 | const id = user?.['role']?.id; |
Nullish Coalescing
In addition, combined with the Nullish Coalescing Operator, Optional Chaining becomes even more succinct as one can specify a value to resolve to rather than the default (undefined
) by simply using a double question mark (??
) notation. For example:
1 2 3 4 5 6 | // assign an empty string as default ... const roleName = user?.role?.name ?? ‘’; // and ... const permissions = user?.role?.getPermissions() ?? []; |
Moreover, Nullish Coalescing, while intended as a compliment to Optional Chaining, also solves additional problems when dealing with falsy values. For instance, consider how many times you may have written something similar to the following:
1 2 3 4 5 6 | // assuming zero is valid, will incorrectly default to 500 ... const refreshRate = preferences.refreshRate || 500; // or perhaps ... const refreshRate = _.isNumber(preferences.refreshRate) ? preferences.refreshRate : 500; |
With the Nullish Coalescing Operator, we can avoid the problems outlined above as only undefined
and null
values will evaluate to true, so falsy values are safe:
1 2 3 4 | // assuming refreshRate is zero, will correctly assign 0 ... const refreshRate = preferences.refreshRate ?? 500; // 0 |
Since Nullish Coalescing only checks for undefined
and null
, the above holds true for all other falsy values, so false
, empty strings
, and NaN
are safe as well..
Optional Chaining w/Destructuring
One thing to note is that Optional Chaining does not resolve when destructuring. So, for example, the following will throw an exception:
1 2 3 4 | const {someProp} = user?.role?.['test']; // TypeError: Cannot destructure property 'someProp' of '(intermediate value)' as it is undefined. |
Interestingly, though, combined with Nullish Coalescing, an exception will not be raised; though, the default will not be assigned, either:
1 2 3 4 | const {someOtherProp} = user?.role?.['test'] ?? false; // undefined |
Concluding Thoughts
As can be seen, ES2020 has no shortage of new features on offer to be excited about and, while arguably not as exciting as other features, Optional Chaining combined with Nullish Coalescing will certainly prove to be valuable additions.
Both Optional Chaining and Nullish Coalescing proposals are currently at Stage 4 and are available in most modern browsers as well as via the following babel
plugins: @babel/plugin-proposal-optional-chaining and @babel/plugin-proposal-nullish-coalescing-operator.