Gloria Harrison
Posted on Sun Aug 14 2022
Updated on : Sun Aug 14 2022
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.
This can be seen as a special case of the logical OR (||
) operator, which returns the right-hand side operand if the left operand is any falsy value, not only 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 (e.g., ''
or 0
). See below for more examples.
The nullish coalescing operator has the fifth-lowest operator precedence, directly lower than ||
and directly higher than the conditional (ternary) operator.
Syntax
leftExpr ?? rightExpr
Copy to Clipboard
Examples
Using the nullish coalescing operator
In this example, we will provide default values but keep values other than null
or undefined
.
const nullValue = null;const emptyText = ""; // falsyconst someNumber = 42;const valA = nullValue ?? "default for A";const valB = emptyText ?? "default for B";const valC = someNumber ?? 0;
console.log(valA); // "default for A"
console.log(valB); // "" (as the empty string is not null or undefined)
console.log(valC); // 42
Copy to Clipboard
Assigning a default value to a variable
Earlier, when one wanted to assign a default value to a variable, a common pattern was to use the logical OR operator (||
):
let foo;// foo is never assigned any value so it is still undefinedconst someDummyText = foo || 'Hello!';
Copy to Clipboard
However, due to ||
being a boolean logical operator, the left-hand-side operand was coerced to a boolean for the evaluation and any falsy value (0
, ''
, NaN
, null
, undefined
) was not returned. This behavior may cause unexpected consequences if you consider 0
, ''
, or NaN
as valid values.
const count = 0;const text = "";const qty = count || 42;const message = text || "hi!";
console.log(qty); // 42 and not 0
console.log(message); // "hi!" and not ""
Copy to Clipboard
The nullish coalescing operator avoids this pitfall by only returning the second operand when the first one evaluates to either null
or undefined
(but no other falsy values):
const myText = ''; // An empty string (which is also a falsy value)const notFalsyText = myText || 'Hello world';
console.log(notFalsyText); // Hello worldconst preservingFalsy = myText ?? 'Hi neighborhood';
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
Copy to Clipboard
Short-circuiting
Like the OR and AND logical operators, the right-hand side expression is not evaluated if the left-hand side proves to be neither null
nor undefined
.
function A() { console.log('A was called'); return undefined;}function B() { console.log('B was called'); return false;}function C() { console.log('C was called'); return "foo";}
console.log(A() ?? C());// logs "A was called" then "C was called" and then "foo"// as A() returned undefined so both expressions are evaluated
console.log(B() ?? C());// logs "B was called" then "false"// as B() returned false (and not null or undefined), the right// hand side expression was not evaluated
Copy to Clipboard
No chaining with AND or OR operators
It is not possible to combine both the AND (&&
) and OR operators (||
) directly with ??
. A SyntaxError
will be thrown in such cases.
null || undefined ?? "foo"; // raises a SyntaxErrortrue || undefined ?? "foo"; // raises a SyntaxError
However, providing parenthesis to explicitly indicate precedence is correct:
(null || undefined) ?? "foo"; // returns "foo"
Relationship with the optional chaining operator (?.
)
The nullish coalescing operator treats undefined
and null
as specific values and so does the optional chaining operator (?.
) which is useful to access a property of an object which may be null
or undefined
.
const foo = { someFooProp: "hi" };
console.log(foo.someFooProp?.toUpperCase() ?? "not available"); // "HI"
console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not available"