[javascript] Is there a "null coalescing" operator in JavaScript?

Is there a null coalescing operator in Javascript?

For example, in C#, I can do this:

String someString = null;
var whatIWant = someString ?? "Cookies!";

The best approximation I can figure out for Javascript is using the conditional operator:

var someString = null;
var whatIWant = someString ? someString : 'Cookies!';

Which is sorta icky IMHO. Can I do better?

The answer is


Need to support old browser and have a object hierarchy

body.head.eyes[0]  //body, head, eyes  may be null 

may use this,

(((body||{}) .head||{}) .eyes||[])[0] ||'left eye'

beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript. 1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

in such case, the type of your variable is actually Object. test it.

window.alert(typeof myEmptyValue); // prints Object
  1. Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

if such case, the type of your variable is 'undefined'.

notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).


Too much talk, there are two items here:

  1. Logical OR

const foo = '' || 'default string';

console.log(foo); // output is 'default string'

  1. Nullish coalescing operator

const foo = '' ?? 'default string';

console.log(foo); // output is empty string i.e. ''

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.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator


function coalesce() {
    var len = arguments.length;
    for (var i=0; i<len; i++) {
        if (arguments[i] !== null && arguments[i] !== undefined) {
            return arguments[i];
        }
    }
    return null;
}

var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);

// xyz.val now contains 5

this solution works like the SQL coalesce function, it accepts any number of arguments, and returns null if none of them have a value. It behaves like the C# ?? operator in the sense that "", false, and 0 are considered NOT NULL and therefore count as actual values. If you come from a .net background, this will be the most natural feeling solution.


Ok a proper answer

Does it exist in JavaScript? Yes, it does. BUT. It's currently as of 2020-02-06 at Stage 3 and is not supported everywhere, yet. Follow the link in URL below and go to the "Specifications" and "Browser compatibility" headers for more info on where it is at.

Quote from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

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.

Contrary to the logical OR (||) operator, the left operand is returned if it is a falsy value which is not null or undefined. In other words, if you use || to provide some default value to another variable foo, you may encounter unexpected behaviors if you consider some falsy values as usable (eg. '' or 0). See below for more examples.

Want examples? Follow the link I posted, it has everything.


beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript. 1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

in such case, the type of your variable is actually Object. test it.

window.alert(typeof myEmptyValue); // prints Object
  1. Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

if such case, the type of your variable is 'undefined'.

notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).


Nobody has mentioned in here the potential for NaN, which--to me--is also a null-ish value. So, I thought I'd add my two-cents.

For the given code:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

If you were to use the || operator, you get the first non-false value:

var result = a || b || c || d || e || f; // result === 1

If you use the typical coalesce method, as posted here, you will get c, which has the value: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

Neither of these seem right to me. In my own little world of coalesce logic, which may differ from your world, I consider undefined, null, and NaN as all being "null-ish". So, I would expect to get back d (zero) from the coalesce method.

If anyone's brain works like mine, and you want to exclude NaN, then this method will accomplish that:

function coalesce() {
    var i, undefined, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg !== null && arg !== undefined
            && (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
            return arg;
        }
    }
    return null;
}

For those who want the code as short as possible, and don't mind a little lack of clarity, you can also use this as suggested by @impinball. This takes advantage of the fact that NaN is never equal to NaN. You can read up more on that here: Why is NaN not equal to NaN?

function coalesce() {
    var i, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg != null && arg === arg ) { //arg === arg is false for NaN
            return arg;
        }
    }
    return null;
}

If || as a replacement of C#'s ?? isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

It will hopefully be available soon in Javascript, as it is in proposal phase as of Apr, 2020. You can monitor the status here for compatibility and support - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

For people using Typescript, you can use the nullish coalescing operator from Typescript 3.7

From the docs -

You can think of this feature - the ?? operator - as a way to “fall back” to a default value when dealing with null or undefined. When we write code like

let x = foo ?? bar();

this is a new way to say that the value foo will be used when it’s “present”; but when it’s null or undefined, calculate bar() in its place.


Yes, it is coming soon. See proposal here and implementation status here.

It looks like this:

x ?? y

Example

const response = {
  settings: {
    nullValue: null,
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false

Note that React's create-react-app tool-chain supports the null-coalescing since version 3.3.0 (released 5.12.2019). From the release notes:

Optional Chaining and Nullish Coalescing Operators

We now support the optional chaining and nullish coalescing operators!

// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined

// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false

This said, in case you use create-react-app 3.3.0+ you can start using the null-coalesce operator already today in your React apps.


Ok a proper answer

Does it exist in JavaScript? Yes, it does. BUT. It's currently as of 2020-02-06 at Stage 3 and is not supported everywhere, yet. Follow the link in URL below and go to the "Specifications" and "Browser compatibility" headers for more info on where it is at.

Quote from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

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.

Contrary to the logical OR (||) operator, the left operand is returned if it is a falsy value which is not null or undefined. In other words, if you use || to provide some default value to another variable foo, you may encounter unexpected behaviors if you consider some falsy values as usable (eg. '' or 0). See below for more examples.

Want examples? Follow the link I posted, it has everything.


After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.

@Gumbo's answer provides the best way to check for null; however, it's important to note the difference in == versus === in JavaScript especially when it comes to issues of checking for undefined and/or null.

There's a really good article about the difference in two terms here. Basically, understand that if you use == instead of ===, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.


function coalesce() {
    var len = arguments.length;
    for (var i=0; i<len; i++) {
        if (arguments[i] !== null && arguments[i] !== undefined) {
            return arguments[i];
        }
    }
    return null;
}

var xyz = {};
xyz.val = coalesce(null, undefined, xyz.val, 5);

// xyz.val now contains 5

this solution works like the SQL coalesce function, it accepts any number of arguments, and returns null if none of them have a value. It behaves like the C# ?? operator in the sense that "", false, and 0 are considered NOT NULL and therefore count as actual values. If you come from a .net background, this will be the most natural feeling solution.


Yes, and its proposal is Stage 4 now. This means that the proposal is ready for inclusion in the formal ECMAScript standard. You can already use it in recent desktop versions of Chrome, Edge and Firefox, but we will have to wait for a bit longer until this feature reaches cross-browser stability.

Have a look at the following example to demonstrate its behavior:

_x000D_
_x000D_
// note: this will work only if you're running latest versions of aforementioned browsers_x000D_
const var1 = undefined;_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = var1 ?? var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_

Previous example is equivalent to:

_x000D_
_x000D_
const var1 = undefined;_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = (var1 !== null && var1 !== undefined) ?_x000D_
    var1 :_x000D_
    var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_

Note that nullish coalescing will not threat falsy values the way the || operator did (it only checks for undefined or null values), hence the following snippet will act as follows:

_x000D_
_x000D_
// note: this will work only if you're running latest versions of aforementioned browsers_x000D_
const var1 = ""; // empty string_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = var1 ?? var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_


For TypesScript users, starting off TypeScript 3.7, this feature is also available now.


Logical nullish assignment, 2020+ solution

A new operator is currently being added to the browsers, ??=. This combines the null coalescing operator ?? with the assignment operator =.

NOTE: This is not common in public browser versions yet. Will update as availability changes.

??= checks if the variable is undefined or null, short-circuiting if already defined. If not, the right-side value is assigned to the variable.

Basic Examples

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

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

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" }

Browser Support Sept 2020 - 3.7%

Mozilla Documentation


beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript. 1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

in such case, the type of your variable is actually Object. test it.

window.alert(typeof myEmptyValue); // prints Object
  1. Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

if such case, the type of your variable is 'undefined'.

notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).


Note that React's create-react-app tool-chain supports the null-coalescing since version 3.3.0 (released 5.12.2019). From the release notes:

Optional Chaining and Nullish Coalescing Operators

We now support the optional chaining and nullish coalescing operators!

// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined

// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false

This said, in case you use create-react-app 3.3.0+ you can start using the null-coalesce operator already today in your React apps.


If || as a replacement of C#'s ?? isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

Logical nullish assignment, 2020+ solution

A new operator is currently being added to the browsers, ??=. This combines the null coalescing operator ?? with the assignment operator =.

NOTE: This is not common in public browser versions yet. Will update as availability changes.

??= checks if the variable is undefined or null, short-circuiting if already defined. If not, the right-side value is assigned to the variable.

Basic Examples

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

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

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" }

Browser Support Sept 2020 - 3.7%

Mozilla Documentation


beware of the JavaScript specific definition of null. there are two definitions for "no value" in javascript. 1. Null: when a variable is null, it means it contains no data in it, but the variable is already defined in the code. like this:

var myEmptyValue = 1;
myEmptyValue = null;
if ( myEmptyValue === null ) { window.alert('it is null'); }
// alerts

in such case, the type of your variable is actually Object. test it.

window.alert(typeof myEmptyValue); // prints Object
  1. Undefined: when a variable has not been defined before in the code, and as expected, it does not contain any value. like this:

    if ( myUndefinedValue === undefined ) { window.alert('it is undefined'); }
    // alerts
    

if such case, the type of your variable is 'undefined'.

notice that if you use the type-converting comparison operator (==), JavaScript will act equally for both of these empty-values. to distinguish between them, always use the type-strict comparison operator (===).


Yes, it is coming soon. See proposal here and implementation status here.

It looks like this:

x ?? y

Example

const response = {
  settings: {
    nullValue: null,
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const undefinedValue = response.settings?.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings?.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings?.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings?.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings?.showSplashScreen ?? true; // result: false

After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.

@Gumbo's answer provides the best way to check for null; however, it's important to note the difference in == versus === in JavaScript especially when it comes to issues of checking for undefined and/or null.

There's a really good article about the difference in two terms here. Basically, understand that if you use == instead of ===, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.


Yes, and its proposal is Stage 4 now. This means that the proposal is ready for inclusion in the formal ECMAScript standard. You can already use it in recent desktop versions of Chrome, Edge and Firefox, but we will have to wait for a bit longer until this feature reaches cross-browser stability.

Have a look at the following example to demonstrate its behavior:

_x000D_
_x000D_
// note: this will work only if you're running latest versions of aforementioned browsers_x000D_
const var1 = undefined;_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = var1 ?? var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_

Previous example is equivalent to:

_x000D_
_x000D_
const var1 = undefined;_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = (var1 !== null && var1 !== undefined) ?_x000D_
    var1 :_x000D_
    var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_

Note that nullish coalescing will not threat falsy values the way the || operator did (it only checks for undefined or null values), hence the following snippet will act as follows:

_x000D_
_x000D_
// note: this will work only if you're running latest versions of aforementioned browsers_x000D_
const var1 = ""; // empty string_x000D_
const var2 = "fallback value";_x000D_
_x000D_
const result = var1 ?? var2;_x000D_
console.log(`Nullish coalescing results in: ${result}`);
_x000D_
_x000D_
_x000D_


For TypesScript users, starting off TypeScript 3.7, this feature is also available now.


If || as a replacement of C#'s ?? isn't good enough in your case, because it swallows empty strings and zeros, you can always write your own function:

 function $N(value, ifnull) {
    if (value === null || value === undefined)
      return ifnull;
    return value;
 }

 var whatIWant = $N(someString, 'Cookies!');

Now it has full support in latest version of major browsers like Chrome, Edge, Firefox , Safari etc. Here's the comparison between the null operator and Nullish Coalescing Operator

const response = {
        settings: {
            nullValue: null,
            height: 400,
            animationDuration: 0,
            headerText: '',
            showSplashScreen: false
        }
    };
    /* OR Operator */
    const undefinedValue = response.settings.undefinedValue || 'Default Value'; // 'Default Value'
    const nullValue = response.settings.nullValue || 'Default Value'; // 'Default Value'
    const headerText = response.settings.headerText || 'Hello, world!'; //  'Hello, world!'
    const animationDuration = response.settings.animationDuration || 300; //  300
    const showSplashScreen = response.settings.showSplashScreen || true; //  true
    /* Nullish Coalescing Operator */
    const undefinedValue = response.settings.undefinedValue ?? 'Default Value'; // 'Default Value'
    const nullValue = response.settings.nullValue ?? ''Default Value'; // 'Default Value'
    const headerText = response.settings.headerText ?? 'Hello, world!'; // ''
    const animationDuration = response.settings.animationDuration ?? 300; // 0
    const showSplashScreen = response.settings.showSplashScreen ?? true; //  false

Need to support old browser and have a object hierarchy

body.head.eyes[0]  //body, head, eyes  may be null 

may use this,

(((body||{}) .head||{}) .eyes||[])[0] ||'left eye'

Too much talk, there are two items here:

  1. Logical OR

const foo = '' || 'default string';

console.log(foo); // output is 'default string'

  1. Nullish coalescing operator

const foo = '' ?? 'default string';

console.log(foo); // output is empty string i.e. ''

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.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator


After reading your clarification, @Ates Goral's answer provides how to perform the same operation you're doing in C# in JavaScript.

@Gumbo's answer provides the best way to check for null; however, it's important to note the difference in == versus === in JavaScript especially when it comes to issues of checking for undefined and/or null.

There's a really good article about the difference in two terms here. Basically, understand that if you use == instead of ===, JavaScript will try to coalesce the values you're comparing and return what the result of the comparison after this coalescence.


Nobody has mentioned in here the potential for NaN, which--to me--is also a null-ish value. So, I thought I'd add my two-cents.

For the given code:

var a,
    b = null,
    c = parseInt('Not a number'),
    d = 0,
    e = '',
    f = 1
;

If you were to use the || operator, you get the first non-false value:

var result = a || b || c || d || e || f; // result === 1

If you use the typical coalesce method, as posted here, you will get c, which has the value: NaN

var result = coalesce(a,b,c,d,e,f); // result.toString() === 'NaN'

Neither of these seem right to me. In my own little world of coalesce logic, which may differ from your world, I consider undefined, null, and NaN as all being "null-ish". So, I would expect to get back d (zero) from the coalesce method.

If anyone's brain works like mine, and you want to exclude NaN, then this method will accomplish that:

function coalesce() {
    var i, undefined, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg !== null && arg !== undefined
            && (typeof arg !== 'number' || arg.toString() !== 'NaN') ) {
            return arg;
        }
    }
    return null;
}

For those who want the code as short as possible, and don't mind a little lack of clarity, you can also use this as suggested by @impinball. This takes advantage of the fact that NaN is never equal to NaN. You can read up more on that here: Why is NaN not equal to NaN?

function coalesce() {
    var i, arg;

    for( i=0; i < arguments.length; i++ ) {
        arg = arguments[i];
        if( arg != null && arg === arg ) { //arg === arg is false for NaN
            return arg;
        }
    }
    return null;
}

It will hopefully be available soon in Javascript, as it is in proposal phase as of Apr, 2020. You can monitor the status here for compatibility and support - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

For people using Typescript, you can use the nullish coalescing operator from Typescript 3.7

From the docs -

You can think of this feature - the ?? operator - as a way to “fall back” to a default value when dealing with null or undefined. When we write code like

let x = foo ?? bar();

this is a new way to say that the value foo will be used when it’s “present”; but when it’s null or undefined, calculate bar() in its place.


Now it has full support in latest version of major browsers like Chrome, Edge, Firefox , Safari etc. Here's the comparison between the null operator and Nullish Coalescing Operator

const response = {
        settings: {
            nullValue: null,
            height: 400,
            animationDuration: 0,
            headerText: '',
            showSplashScreen: false
        }
    };
    /* OR Operator */
    const undefinedValue = response.settings.undefinedValue || 'Default Value'; // 'Default Value'
    const nullValue = response.settings.nullValue || 'Default Value'; // 'Default Value'
    const headerText = response.settings.headerText || 'Hello, world!'; //  'Hello, world!'
    const animationDuration = response.settings.animationDuration || 300; //  300
    const showSplashScreen = response.settings.showSplashScreen || true; //  true
    /* Nullish Coalescing Operator */
    const undefinedValue = response.settings.undefinedValue ?? 'Default Value'; // 'Default Value'
    const nullValue = response.settings.nullValue ?? ''Default Value'; // 'Default Value'
    const headerText = response.settings.headerText ?? 'Hello, world!'; // ''
    const animationDuration = response.settings.animationDuration ?? 300; // 0
    const showSplashScreen = response.settings.showSplashScreen ?? true; //  false