51

Nullish coalescing operator allows assigning a variable if it's not null or undefined, or an expression otherwise.

a = b ?? other

It is an improvement over previously used || because || will also assign other if b is empty string or other falsy, but not nullish value.

However, sometimes, we also use && for value assignment, for example

a = b && func(b)

where we only want to do func on b if it's not nullish, otherwise assign the nullish b.

Of course, && checks for falsiness, not nullishness. Is there a nullish version of &&?

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
f.khantsis
  • 3,256
  • 5
  • 50
  • 67
  • 4
    To my knowledge, there is no such operator (and not even a proposal). But you can use the following instead: `a = b == null ? b : func(b)`. – str Jul 16 '20 at 07:22
  • 1
    double equal sign with null sounds scary – f.khantsis Jul 16 '20 at 07:22
  • 4
    Why? It is [the way to check for nullish values](https://tc39.es/ecma262/#sec-abstract-equality-comparison). – str Jul 16 '20 at 07:25
  • 1
    @f.khantsis `x == null` will *only* return `true` if `x = null` or `x = undefined`. As such, it's the exact match of the nullish coalescing behaviour which only activates for those values. – VLAZ Jul 16 '20 at 07:25
  • @str, if `b`is `null` it would already be truthy and that would just make `a` `null`. Do this instead: `let a = b === null ? other : func(b);` – StackSlave Jul 16 '20 at 07:32
  • 4
    @StackSlave "*do func on b if it's not nullish, otherwise assign the nullish b*" seems exactly what my code is doing. – str Jul 16 '20 at 07:38
  • Sorry for intervention, here is what TSC generates: ```const a = b !== null && b !== void 0 ? b : func(b);``` Simplifed version would be exact @f.khantsis provided: ```b==null ? func(b): b```` – Drag13 Jul 16 '20 at 07:46

6 Answers6

21

To my knowledge, there is no such operator and also no proposal to add one. Instead you can rely on the standard way to check for nullish values: b == null

a = b == null ? b : func(b)
str
  • 42,689
  • 17
  • 109
  • 127
  • If `b` is `false`, with this approach is treated as an undefined or null, so trigger `func(b)` – Chu May 19 '21 at 03:31
  • @Chu If `b` is nullish (only `null` or `undefined`), the function will *not* run. If `b` is anything else (including `false`) the function *will* run, and its result will be assigned to `a`. Try running `false == null` in your browser console. – forresthopkinsa Aug 03 '21 at 02:31
  • How about `a = b == null && func(b)`? Or if your linting config forbids the use of `==`, then `a = (b === null || b === undefined) && func(b)` – Matt Browne Feb 05 '22 at 00:46
  • 1
    Oh my, I've used so many triple equals `===` that I completely forgot about `undefined == null`. – Qwerty Aug 26 '22 at 02:18
  • 1
    @MattBrowne Even if your linter forbids ===, it should still allow == null as a special case. However, you end up with `false | T` in this case, which is not great (especially if you plan to use it again in the same way). – riv Jun 12 '23 at 07:49
8

This will not answer the question since it was already answered by @str, I'm just posting this here because I don't have enough rep to comment on @Dalou's answer and don't want people to trip on that answer.

a = (b ?? false) && other

Is not the opposite of ??, since a will take the value of b if b is a falsy value other than undefined/null, like '' or 0 for example. The opposite of ?? should set a to the value of other even if b is '' or 0.

Luis Pais
  • 89
  • 2
  • 3
3

ANSWER:

let a = 9;

if( a!==null || a!==undefined ){ /* actions */ };

if( (a??null) !== null ){ /* actions */ }

PROPOSAL:

const oo = console.log;
let a; // undefined, null

// Syntax proposal: !?
a !? oo('NOT Nullish coalescing operator');

// Logical NOT Nullish assignment:
let a = 7;
a !?= 5;
oo(a); // 5

let b, c = null;
b !?= 3;
oo(b); // undefined
c !?= 8;
oo(c); // null
Teamur
  • 67
  • 1
  • 4
1

There's currently no such operator, as others have already pointed out. However, there are a few proposals for exactly this operator in the official TC39 discourse group:

If you're interested in bringing this into ECMA, these might be good places to start.

Sebastian
  • 503
  • 5
  • 11
0

I don't like it but here's my solution:

output = typeof input === 'boolean' && "other"

Truth table:

input     -> output
--------------------
null      -> false
undefined -> false
true      -> "other"
false     -> "other"
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Kolby Watson
  • 483
  • 1
  • 4
  • 6
0

I just found this post today, and I thought to add my few words on it.

Although, inverse null coalescing operator is in the proposal:

a = b !? func(b)

I don't think this proposal will be implemented and is a must have feature since we can simply get desired behaviors with && and || operators. The add of ?? is special feature and is a must have feature. This is just my opinion.

I don't think we should wait than simply using like:

a = func(b??false)

We just need to be creative! I have used here nullish coalescing operator directly inside the function call so we avoided the need of inversing it like:

a = b != null && func(b) or so on

So, I opine to have !? is completely unnecessary. We just need to think it correctly.

"Something not null then have it" can be simply be denoted with nullish coalescing operator: (HAVE_IT ?? false) || (HAVE_IT ?? 0) || (HAVE_IT ?? ANYTHING_YOU_WANT_EXCEPT_NULL).

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231