语法错误:不能在 `||` 和 `&&` 表达式中使用不带括号的 `??`
当 空值合并运算符 在不带括号的同一表达式中与 逻辑或 或 逻辑与 一起使用时,会出现 JavaScript 异常“不能在 ||
和 &&
表达式中使用不带括号的 ??
”。
¥The JavaScript exception "cannot use ??
unparenthesized within ||
and &&
expressions" occurs when an nullish coalescing operator is used with a logical OR or logical AND in the same expression without parentheses.
信息
¥Message
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)
错误类型
什么地方出了错?
¥What went wrong?
运算符优先级 链如下所示:
¥The operator precedence chain looks like this:
| > && > || > = | > ?? > =
但是,故意未定义 ??
和 &&
/||
之间的优先级,因为逻辑运算符的短路行为可能会使表达式的计算违反直觉。因此,以下组合都是语法错误,因为语言不知道如何给操作数加上括号:
¥However, the precedence between ??
and &&
/||
is intentionally undefined, because the short circuiting behavior of logical operators can make the expression's evaluation counter-intuitive. Therefore, the following combinations are all syntax errors, because the language doesn't know how to parenthesize the operands:
a ?? b || c;
a || b ?? c;
a ?? b && c;
a && b ?? c;
相反,通过明确地在任一侧加上括号来明确你的意图:
¥Instead, make your intent clear by parenthesizing either side explicitly:
(a ?? b) || c;
a ?? (b && c);
示例
¥Examples
当迁移使用 ||
和 &&
来防御 null
或 undefined
的旧代码时,你通常可能会对其进行部分转换:
¥When migrating legacy code that uses ||
and &&
for guarding against null
or undefined
, you may often convert it partially:
function getId(user, fallback) {
// Previously: user && user.id || fallback
return user && user.id ?? fallback; // SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions
}
相反,请考虑将 &&
添加括号:
¥Instead, consider parenthesizing the &&
:
function getId(user, fallback) {
return (user && user.id) ?? fallback;
}
更好的是,考虑使用 可选链接 而不是 &&
:
¥Even better, consider using optional chaining instead of &&
:
function getId(user, fallback) {
return user?.id ?? fallback;
}
也可以看看
¥See also
- TC39 无效合并提案中的 关于无效合并优先级的问题
- 空合并运算符 (
??
) - 运算符优先级