SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions

空值合并运算符(nullish coalescing operator)在同一个表达式中不加括号地与逻辑或(logical OR)逻辑与(logical AND)一起使用时,会发生 JavaScript 异常 "不能在 ||&& 表达式中不加括号地使用 ??"。

消息

SyntaxError: Unexpected token '??' (V8-based)
SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions (Firefox)
SyntaxError: Unexpected token '??'. Coalescing and logical operators used together in the same expression; parentheses must be used to disambiguate. (Safari)

错误类型

SyntaxError

哪里出错了?

运算符优先级链如下所示

|   >   &&   >   ||   >   =
|   >   ??   >   =

然而,??&&/|| 之间的优先级是故意未定义的,因为逻辑运算符的短路行为可能会使表达式的评估反直觉。因此,以下所有组合都是语法错误,因为语言不知道如何对操作数进行括号化

js
a ?? b || c;
a || b ?? c;
a ?? b && c;
a && b ?? c;

相反,通过显式地将任一侧加上括号来明确你的意图

js
(a ?? b) || c;
a ?? (b && c);

示例

在迁移使用 ||&& 来防止 nullundefined 的旧代码时,你可能经常会部分转换它

js
function getId(user, fallback) {
  // Previously: user && user.id || fallback
  return user && user.id ?? fallback; // SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions
}

相反,考虑将 && 括起来

js
function getId(user, fallback) {
  return (user && user.id) ?? fallback;
}

甚至更好,考虑使用可选链(optional chaining)而不是 &&

js
function getId(user, fallback) {
  return user?.id ?? fallback;
}

另见