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.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone
https://github.com/mdn/interactive-examples
and send us a pull request.
见
PR #1482
regarding the addition of this example.
leftExpr ?? rightExpr
In this example, we will provide default values but keep values other than
null
or
undefined
.
const nullValue = null; const emptyText = ""; // falsy const 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
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 undefined let someDummyText = foo || 'Hello!';
However, due to
||
being a boolean logical operator, the left hand-side operand was coerced to a boolean for the evaluation and any
falsy
值 (
0
,
''
,
NaN
,
null
,
undefined
) was not returned. This behavior may cause unexpected consequences if you consider
0
,
''
,或
NaN
as valid values.
let count = 0; let text = ""; let qty = count || 42; let message = text || "hi!"; console.log(qty); // 42 and not 0 console.log(message); // "hi!" and not ""
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):
let myText = ''; // An empty string (which is also a falsy value) let notFalsyText = myText || 'Hello world'; console.log(notFalsyText); // Hello world let preservingFalsy = myText ?? 'Hi neighborhood'; console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
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
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 SyntaxError true || undefined ?? "foo"; // raises a SyntaxError
However, providing parenthesis to explicitly indicate precedence is correct:
(null || undefined) ?? "foo"; // returns "foo"
?.
)
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
.
let foo = { someFooProp: "hi" };
console.log(foo.someFooProp?.toUpperCase() ?? "not available"); // "HI"
console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not available"
| 规范 |
|---|
|
ECMAScript (ECMA-262)
The definition of 'nullish coalescing expression' in that specification. |
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Nullish coalescing operator (
??
)
|
Chrome 80 | Edge 80 | Firefox 72 | IE No | Opera 67 | Safari 13.1 | WebView Android 80 | Chrome Android 80 | Firefox Android No | Opera Android No | Safari iOS 13.4 | Samsung Internet Android No | nodejs 14.0.0 |
完整支持
不支持
The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262 , the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.