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.
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.
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';
Videos
For some years now it is simply
a?.b?.c
a?.b?.c ?? "default"
Check "Can I Use" for compatibility: https://caniuse.com/mdn-javascript_operators_optional_chaining,mdn-javascript_operators_nullish_coalescing
Update (2022-01-13): Seems people are still finding this, here's the current story:
- Optional Chaining is in the specification now (ES2020) and supported by all modern browsers, more in the archived proposal: https://github.com/tc39/proposal-optional-chaining
- babel-preset-env: If you need to support older environments that don't have it, this is probably what you want https://babeljs.io/docs/en/babel-preset-env
- Babel v7 Plugin: https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining
Update (2017-08-01): If you want to use an official plugin, you can try the alpha build of Babel 7 with the new transform. Your mileage may vary
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Original:
A feature that accomplishes that is currently in stage 1: Optional Chaining.
https://github.com/tc39/proposal-optional-chaining
If you want to use it today, there is a Babel plugin that accomplishes that.
https://github.com/davidyaha/ecmascript-optionals-proposal
It's not as nice as the ?. operator, but to achieve a similar result you could do:
user && user.address && user.address.postcode
Since null and undefined are both falsy values (see this reference), the property after the && operator is only accessed if the precedent it not null or undefined.
Alternatively, you could write a function like this:
function _try(func, fallbackValue) {
try {
var value = func();
return (value === null || value === undefined) ? fallbackValue : value;
} catch (e) {
return fallbackValue;
}
}
Usage:
_try(() => user.address.postcode) // return postcode or undefined
Or, with a fallback value:
_try(() => user.address.postcode, "none") // return postcode or a custom string
Called "optional chaining", it's currently a TC39 proposal in Stage 4. A Babel plugin however is already available in v7.
Example usage:
const obj = {
foo: {
bar: {
baz: 42,
},
},
};
const baz = obj?.foo?.bar?.baz; // 42
const safe = obj?.qux?.baz; // undefined
Js logical operators return not true or false, but truly or falsy value itself. For example in expression x && y, if x is falsy, then it will be returned, otherwise y will be returned. So the truth table for operator is correct.
In your case you could use expression customers && customers.orders && customers.orders.Length to get length value or the first falsy one.
Also you can do some magic like ((customers || {}).orders || {}).length
(Personally, I don't like this syntax and possible garbage collection pressure as well)
Or even use maybe monad.
function Option(value) {
this.value = value;
this.hasValue = !!value;
}
Option.prototype.map = function(s) {
return this.hasValue
? new Option(this.value[s])
: this;
}
Option.prototype.valueOrNull = function() {
return this.hasValue ? this.value : null;
}
var length =
new Option(customers)
.map("orders")
.map("length")
.valueOrNull();
It's longer than all the previous approaches, but clearly shows your intentions without any magic behind.
I'm working on a large code base written in JavaScript (no TypeScript) and Vue.
Recently, we refactored a big chunk of our application core code and experienced some bugs due to it, which fortunately have been logged, identified and fixed. A key problem of ours was that many object accesses happened on null and undefined. I think this could have been avoided if there were some kinds of warnings when we try to access properties of an object that could be null or undefined.
We already annotated these objects in question with JSDoc which gives us the correct properties that we could access, but our IDE (PHPStorm) doesn't notify us about null access. Although there seems to be some mechanism to warn about null, like in this example:
const foo = null; const bar = foo.baz; // -> marks foo with the message: 'foo is null'
But if we had an annotated variable defined in another context, we don't see any warning whatsoever
/**
* @type {{baz: string}|null}
*/
const foo = null;
function accessFoo(){
const bar = foo.baz; // just works, bar has type string now
}Is this specific to our IDE in use? Is there any way to catch these errors? For now, we can't migrate to TypeScript (where I know that this is configurable) but ideally it would work similarly. But we would be happy with anything that makes it a bit easier for us to reason about null access.