空值合并运算符 (??)
试一试
语法
js
leftExpr ?? rightExpr
描述
空值合并运算符可以看作是 逻辑或 (||
) 运算符 的特例。后者当左侧操作数为任何 假值 时返回右侧操作数,而不仅仅是 null
或 undefined
。换句话说,如果您使用 ||
为另一个变量 foo
提供一些默认值,如果您认为某些假值可用(例如 ''
或 0
),可能会遇到意外行为。有关更多示例,请参阅 下方。
空值合并运算符具有第五低的 运算符优先级,直接低于 ||
,直接高于 条件(三元)运算符。
无法将 AND (&&
) 和 OR 运算符 (||
) 直接与 ??
组合。在这种情况下,将抛出 语法错误。
js
null || undefined ?? "foo"; // raises a SyntaxError
true && undefined ?? "foo"; // raises a SyntaxError
相反,请提供括号以明确指示优先级。
js
(null || undefined) ?? "foo"; // returns "foo"
示例
使用空值合并运算符
在本例中,我们将提供默认值,但保留除 null
或 undefined
之外的值。
js
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
为变量分配默认值
之前,当人们想要为变量分配默认值时,常见的模式是使用逻辑或运算符 (||
)
js
let foo;
// foo is never assigned any value so it is still undefined
const someDummyText = foo || "Hello!";
但是,由于 ||
是布尔逻辑运算符,因此左侧操作数将被强制转换为布尔值以进行评估,并且任何假值(包括 0
、''
、NaN
、false
等)都不会被返回。如果您认为 0
、''
或 NaN
是有效值,这种行为可能会导致意外后果。
js
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 ""
空值合并运算符避免了这种陷阱,因为它仅在第一个操作数评估为 null
或 undefined
(但不是其他假值)时才返回第二个操作数。
js
const myText = ""; // An empty string (which is also a falsy value)
const notFalsyText = myText || "Hello world";
console.log(notFalsyText); // Hello world
const preservingFalsy = myText ?? "Hi neighborhood";
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
短路
与 'OR' 和 'AND' 逻辑运算符一样,如果左侧表达式被证明既不是 null
也不是 undefined
,则不会评估右侧表达式。
js
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
与可选链运算符 (?. ) 的关系
空值合并运算符将 undefined
和 null
视为特定值。 可选链运算符 (?.
) 也是如此,它对于访问可能为 null
或 undefined
的对象的属性很有用。将它们组合起来,您可以安全地访问可能为空值的属性的对象的属性,并在它是空值时提供默认值。
js
const foo = { someFooProp: "hi" };
console.log(foo.someFooProp?.toUpperCase() ?? "not available"); // "HI"
console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not available"
规范
规范 |
---|
ECMAScript 语言规范 # prod-CoalesceExpression |
浏览器兼容性
BCD 表格仅在浏览器中加载