Is There a Null-Coalescing (Elvis) Operator or Safe Navigation Operator in JavaScript

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.

Does ES6 support the Elvis operator?

No, but you can just use || or &&, seems to perform same function.

var debug = true;
debug && console.log("debug mode on ");
debug || console.log("debug mode off");

What does ?? ternary operator mean using react and javascript?

First, as already pointed out, this isn't specific to React, but plain JavaScript syntax.

Let's break it down.

Optional Chaining ?.

const result1 = data?.item?.someItem?.count

The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.

So even if data, item or someItem is undefined or null, you could still use this statement without generating an error, but you would simply get an undefined value.

Read more about it in the docs here.

Nullish coalescing operator (??)

const result2 = result1 ?? 0

As described in the docs:

The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

In your case, the expression will return 0 if element is null or undefined, otherwise it returns element.

Final output: Strict Equality Comparison

const output = result2 === 0

The expression evaluates to true if result2 is strictly equal to the numeric value 0. Also read the docs here.

What does ?. and ?? mean in javascript

1. Optional chaining (?.)

From MDN said that

The optional chaining operator (?.) permits reading the value of a
property located deep within a chain of connected objects without
having to expressly validate that each reference in the chain is
valid.

The ?. operator functions similarly to the . chaining operator, except
that instead of causing an error if a reference is nullish (null or
undefined)
, the expression short-circuits with a return value of
undefined. When used with function calls, it returns undefined if the
given function does not exist.

const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};

console.log(adventurer.dog?.name); // expected output: undefined

console.log(adventurer.dog.name); // Thow an error message like
//`"message": "Uncaught TypeError: Cannot read property 'name' of undefined",`

Is there a way to utilize the nullish coalescing operator (`??`) in object property destructuring?

I see two possible options:

  1. Do the nullish coalescing property-by-property, or

  2. Use a utility function

Property by property

Fairly plodding (I'm a plodding developer):

// Default `ExampleProps` here −−−−−−−−−−−−−−−vvvvv
export default function Example({ ExampleProps = {} }) {
// Then do the nullish coalescing per-item
const content = ExampleProps.content ?? "";
const title = ExampleProps.title ?? "Missing Title";
const date = ExampleProps.date ?? "";
const featuredImage = ExampleProps.featuredImage ?? {},
const author = ExampleProps.author ?? {},
const tags = ExampleProps.tags ?? [];
// ...

Utility function

Alternatively, use a utility function along these lines to convert null values (both compile-time and runtime) to undefined, so you can use destructuring defaults when destructuring the result. The type part is fairly straightforward:

type NullToUndefined<Type> = {
[key in keyof Type]: Exclude<Type[key], null>;
}

Then the utility function could be something like this:

function nullToUndefined<
SourceType extends object,
ResultType = NullToUndefined<SourceType>
>(object: SourceType) {
return Object.fromEntries(
Object.entries(object).map(([key, value]) => [key, value ?? undefined])
) as ResultType;
}

or like this (probably more efficient in runtime terms):

function nullToUndefined<
SourceType extends object,
ResultType = NullToUndefined<SourceType>
>(object: SourceType) {
const source = object as {[key: string]: any};
const result: {[key: string]: any} = {};
for (const key in object) {
if (Object.hasOwn(object, key)) {
result[key] = source[key] ?? undefined;
}
}
return result as ResultType;
}

Note that Object.hasOwn is very new, but easily polyfilled. Or you could use Object.prototype.hasOwn.call(object, key) instead.

(In both cases within nullToUndefined I'm playing a bit fast and loose with type assertions. For a small utility function like that, I think that's a reasonable compromise provided the inputs and outputs are well-defined.)

Then:

export default function Example({ ExampleProps }) {
const {
content = "",
title = "Missing Title",
date = "",
featuredImage = {},
author = {},
tags = [],
} = nullToUndefined(ExampleProps || {});
// ^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−^
// ...

Playground link

Null checks for elements with optional chaining

Yes, Optional Chaining is really tidy and neat way not only for Null verification but undefined as well with JS.

It allows you to make your code readable as well as less cluttered.

I'll suggest to deep more into Optional Chaining to use it's fantastic features.

Ref Link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Comparison of Ternary operator, Elvis operator, safe Navigation Operator and logical OR operators

update

With TypeScript 3.7 they've implemented Optional Chaining, which is like the safe navigation operator, but then better. Also the Nullish Coalescing has found its way to the scene.

If you are using this version, the below answer is obsolete


Maybe I've missed a couple versions, but to my knowledge, TypeScript does not have an elvis operator or a safe navigation operator. The only extra thing they have is a non-null assertion operator !., but this is only for the compiler, and in the compiled js the ! will be removed. Angular however, does have the safe navigation operator inside their templates, but under the hood this will resolve into a logical or ||. The benefit here is increased readability and smaller templates.

Besides that, TypeScript does have the ?: notation, but this is used in interfaces or method parameters to indicate that the value is optional

Which leaves us with the ternary operator vs logical or. You would use the first one if there are 3 values. The question, the answer yes result, and the answer no result to said question.

And the latter when there are 2 values. Where the first one, if resolved to truthy will be the answer, and otherwise the second one, regardless of its value.

Benefit wise, I can't really say much. I would expect them to be equally fast, with a marginal difference. Perhaps readability is increased with the ternary option, which you obviously can always use instead of the logical or ||, but personally I like to use the ||, because it keeps the code compact.

TLDR;

  • Ternary Operator

Simplified if else, available everywhere

  • Elvis operator ?:

Not available in typescript/javascript/angular and essentially the same as ||

  • Safe navigation operator ?.

Only available in angular templating, used to prevent null pointers in object parameter navigation

  • Logical or ||

If not left hand, then right hand. Even more simplified if else. Available in typescript/javascript/angular



Related Topics



Leave a reply



Submit