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);
示例
在迁移使用 || 和 && 来防止 null 或 undefined 的旧代码时,你可能经常会部分转换它
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;
}
另见
- TC39 空值合并提案中关于空值合并优先级的问题
- 空值合并运算符(
??) - 运算符优先级