[javascript] Replace a value if null or undefined in JavaScript

I have a requirement to apply the ?? C# operator to JavaScript and I don't know how. Consider this in C#:

int i?=null;
int j=i ?? 10;//j is now 10

Now I have this set up in JavaScript:

var options={
       filters:{
          firstName:'abc'
       } 
    };
var filter=options.filters[0]||'';//should get 'abc' here, it doesn't happen
var filter2=options.filters[1]||'';//should get empty string here, because there is only one filter

How do I do it correctly?

Thanks.

EDIT: I spotted half of the problem: I can't use the 'indexer' notation to objects (my_object[0]). Is there a way to bypass it? (I don't know the names of the filters properties beforehand and don't want to iterate over them).

This question is related to javascript

The answer is


Destructuring solution

Question content may have changed, so I'll try to answer thoroughly.

Destructuring allows you to pull values out of anything with properties. You can also define default values when null/undefined and name aliases.

const options = {
    filters : {
        firstName : "abc"
    } 
}

const {filters: {firstName = "John", lastName = "Smith"}} = options

// firstName = "abc"
// lastName = "Smith"

NOTE: Capitalization matters

If working with an array, here is how you do it.

In this case, name is extracted from each object in the array, and given its own alias. Since the object might not exist = {} was also added.

const options = {
    filters: [{
        name: "abc",
        value: "lots"
    }]
}

const {filters:[{name : filter1 = "John"} = {}, {name : filter2 = "Smith"} = {}]} = options

// filter1 = "abc"
// filter2 = "Smith"

More Detailed Tutorial

Browser Support 92% July 2020


I spotted half of the problem: I can't use the 'indexer' notation to objects (my_object[0]). Is there a way to bypass it?

No; an object literal, as the name implies, is an object, and not an array, so you cannot simply retrieve a property based on an index, since there is no specific order of their properties. The only way to retrieve their values is by using the specific name:

var someVar = options.filters.firstName; //Returns 'abc'

Or by iterating over them using the for ... in loop:

for(var p in options.filters) {
    var someVar = options.filters[p]; //Returns the property being iterated
}

ES2020 Answer

The new Nullish Coalescing Operator, is finally available on JavaScript, though browser support is limited. According to the data from caniuse, only 48.34% of browsers are supported (as of April 2020).

According to the documentation,

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.

const options={
  filters:{
    firstName:'abc'
  } 
};
const filter = options.filters[0] ?? '';
const filter2 = options.filters[1] ?? '';

This will ensure that both of your variables will have a fallback value of '' if filters[0] or filters[1] are null, or undefined.

Do take note that the nullish coalescing operator does not return the default value for other types of falsy value such as 0 and ''. If you wish to account for all falsy values, you should be using the OR operator ||.


?? should be preferred to || because it checks only for nulls and undefined.

All The expressions below are true:

(null || 'x') === 'x' ;
(undefined || 'x') === 'x' ;
//Most of the times you don't want the result below
('' || 'x') === 'x'  ;
(0 || 'x') === 'x' ;
(false || 'x') === 'x' ;
//-----

//Using ?? is preferred
(null ?? 'x') === 'x' ;
(undefined ?? 'x') === 'x' ;
//?? works only for null and undefined, which is in general safer
('' ?? 'x') === '' ;
(0 ?? 'x') === 0 ;
(false ?? 'x') === false ;

Bottom line:

int j=i ?? 10; is perfectly fine to use in javascript also. Just replace int with let.

Asterisk: Check browser compatibility and if you really need to support these other browsers use babel.


Logical nullish assignment, 2020+ solution

A new operator has been added, ??=. This is equivalent to value = value ?? defaultValue.

||= and &&= are similar, links below.

This checks if left side is undefined or null, short-circuiting if already defined. If not, the left side is assigned the right-side value.

Basic Examples

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

// Equivalent to
a = a ?? true

Object/Array Examples

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

Functional Example

function config(options) {
    options.duration ??= 100
    options.speed ??= 25
    return options
}

config({ duration: 555 })   // { duration: 555, speed: 25 }
config({})                  // { duration: 100, speed: 25 }
config({ duration: null })  // { duration: 100, speed: 25 }

??= Browser Support Nov 2020 - 77%

??= Mozilla Documentation

||= Mozilla Documentation

&&= Mozilla Documentation