Nullish coalescing operator

空值合并运算符(??是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。

逻辑或(||)操作符不同,逻辑或会在左操作数为 假值  时返回右侧操作数。也就是说,如果你使用 || 来为某些变量设置默认的值时,你可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。

语法

leftExpr ?? rightExpr

描述

空值合并运算符会在左侧的表达式为 null 或 undefined 时返回右侧的表达式。

为变量赋默认值

在早期,如果想为一个变量赋默认值,通常的做法是使用逻辑或操作符(||):

let foo;

//  foo is never assigned any value so it is still undefined
let someDummyText = foo || 'Hello!';

然而由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(0, '', NaN, null, undefined)都不会被返回。这导致如果你使用0''NaN作为有效值,就会出现不可预料的后果。

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

空值合并操作符可以避免这种陷阱,其只在第一个操作数为null 或 undefined 时(而不是其它假值)返回第二个操作数:

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)

短路

与 OR 和 AND 逻辑操作符相似,当左表达式不为 null 或 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

不能与 AND 或 OR 操作符共用

直接与 AND(&&)和 OR(||)操作符组合使用 ?? 是不可取的。这种情况下会抛出 SyntaxError

null || undefined ?? "foo"; // raises a SyntaxError
true || undefined ?? "foo"; // raises a SyntaxError

但当使用括号来显式表明优先级时是正确的:

(null || undefined ) ?? "foo"; // returns "foo"

与可选链式操作符(?.)的关系

空值合并操作符针对 undefined 与 null 这两个值,可选链式操作符(?. 也是如此。在这访问属性可能为 undefined 与 null 的对象时非常有用。

let foo = { someFooProp: "hi" };

console.log(foo.someFooProp?.toUpperCase());  // "HI"
console.log(foo.someBarProp?.toUpperCase()); // undefined

样例

在这个例子中,我们会提供默认值,但对原有值不为 undefined 与 null 的进行保留。

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

规范

Specification Status Comment
Proposal for the "nullish coalescing" operator Stage 4

浏览器兼容性

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Nullish coalescing operator (??)Chrome Full support 80Edge No support NoFirefox Full support 72IE No support NoOpera No support NoSafari No support NoWebView Android Full support 80Chrome Android Full support 80Firefox Android No support NoOpera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs No support No

Legend

Full support  
Full support
No support  
No support

Implementation Progress

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.

See also