Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a null-coalescing (Elvis) operator or safe navigation operator in javascript?

You can use the logical 'OR' operator in place of the Elvis operator:

For example displayname = user.name || "Anonymous" .

But Javascript currently doesn't have the other functionality. I'd recommend looking at CoffeeScript if you want an alternative syntax. It has some shorthand that is similar to what you are looking for.

For example The Existential Operator

zip = lottery.drawWinner?().address?.zipcode

Function shortcuts

()->  // equivalent to function(){}

Sexy function calling

func 'arg1','arg2' // equivalent to func('arg1','arg2')

There is also multiline comments and classes. Obviously you have to compile this to javascript or insert into the page as <script type='text/coffeescript>' but it adds a lot of functionality :) . Using <script type='text/coffeescript'> is really only intended for development and not production.


I think the following is equivalent to the safe navigation operator, although a bit longer:

var streetName = user && user.address && user.address.street;

streetName will then be either the value of user.address.street or undefined.

If you want it to default to something else you can combine with the above shortcut or to give:

var streetName = (user && user.address && user.address.street) || "Unknown Street";

2020 Update

JavaScript now has equivalents for both the Elvis Operator and the Safe Navigation Operator.


Safe Property Access

The optional chaining operator (?.) is currently a stage 4 ECMAScript proposal. You can use it today with Babel.

// `undefined` if either `a` or `b` are `null`/`undefined`. `a.b.c` otherwise.
const myVariable = a?.b?.c;

The logical AND operator (&&) is the "old", more-verbose way to handle this scenario.

const myVariable = a && a.b && a.b.c;

Providing a Default

The nullish coalescing operator (??) is currently a stage 4 ECMAScript proposal. You can use it today with Babel. It allows you to set a default value if the left-hand side of the operator is a nullary value (null/undefined).

const myVariable = a?.b?.c ?? 'Some other value';

// Evaluates to 'Some other value'
const myVariable2 = null ?? 'Some other value';

// Evaluates to ''
const myVariable3 = '' ?? 'Some other value';

The logical OR operator (||) is an alternative solution with slightly different behavior. It allows you to set a default value if the left-hand side of the operator is falsy. Note that the result of myVariable3 below differs from myVariable3 above.

const myVariable = a?.b?.c || 'Some other value';

// Evaluates to 'Some other value'
const myVariable2 = null || 'Some other value';

// Evaluates to 'Some other value'
const myVariable3 = '' || 'Some other value';

Javascript's logical OR operator is short-circuiting and can replace your "Elvis" operator:

var displayName = user.name || "Anonymous";

However, to my knowledge there's no equivalent to your ?. operator.


I've occasionally found the following idiom useful:

a?.b?.c

can be rewritten as:

((a||{}).b||{}).c

This takes advantage of the fact that getting unknown attributes on an object returns undefined, rather than throwing an exception as it does on null or undefined, so we replace null and undefined with an empty object before navigating.


i think lodash _.get() can help here, as in _.get(user, 'name'), and more complex tasks like _.get(o, 'a[0].b.c', 'default-value')


There is currently a draft spec:

https://github.com/tc39/proposal-optional-chaining

https://tc39.github.io/proposal-optional-chaining/

For now, though, I like to use lodash get(object, path [,defaultValue]) or dlv delve(obj, keypath)

Update (as of Dec 23, 2019):

optional chaining has moved to stage 4