语法错误:无括号的一元表达式不能出现在 '**' 的左侧

当在不带括号的 求幂运算符 的左操作数上使用一元运算符(typeofvoiddeleteawait!~+- 之一)时,会发生 JavaScript 异常 "无括号的一元表达式不能出现在 '**' 的左侧"。

¥The JavaScript exception "unparenthesized unary expression can't appear on the left-hand side of '**'" occurs when a unary operator (one of typeof, void, delete, await, !, ~, +, -) is used on the left operand of the exponentiation operator without parentheses.

信息

¥Message

SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence (V8-based)
SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '**' (Firefox)
SyntaxError: Unexpected token '**'. Ambiguous unary expression in the left hand side of the exponentiation expression; parentheses must be used to disambiguate the expression. (Safari)

错误类型

¥Error type

SyntaxError

什么地方出了错?

¥What went wrong?

你可能写过这样的东西:

¥You likely wrote something like this:

js
-a ** b

到底应该评价为 (-a) ** b 还是 -(a ** b) 是不明确的。在数学中,-x2 表示 -(x ** 2) — 这就是包括 Python、Haskell 和 PHP 在内的许多语言处理它的数量。但是,使一元减运算符优先于 ** 会破坏与 a ** -b 的对称性,而 a ** -b 无疑是 a ** (-b)。因此,该语言禁止这种语法,并要求你在两边加上括号来解决歧义。

¥Whether it should be evaluated as (-a) ** b or -(a ** b) is ambiguous. In mathematics, -x2 means -(x ** 2) — and that's how many languages, including Python, Haskell, and PHP, handle it. But making the unary minus operator take precedence over ** breaks symmetry with a ** -b, which is unambiguously a ** (-b). Therefore, the language forbids this syntax and requires you to parenthesize either side to resolve the ambiguity.

js
(-a) ** b
-(a ** b)

其他一元运算符也不能位于求幂的左侧。

¥Other unary operators cannot be the left-hand side of exponentiation either.

js
await a ** b
!a ** b
+a ** b
~a ** b

示例

¥Examples

当编写涉及求幂的复杂数学表达式时,你可以编写如下内容:

¥When writing complex math expressions involving exponentiation, you may write something like this:

js
function taylorSin(x) {
  return (n) => (-1 ** n * x ** (2 * n + 1)) / factorial(2 * n + 1);
  // SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '**'
}

然而,-1 ** n 部分在 JavaScript 中是非法的。相反,将左操作数加上括号:

¥However, the -1 ** n part is illegal in JavaScript. Instead, parenthesize the left operand:

js
function taylorSin(x) {
  return (n) => ((-1) ** n * x ** (2 * n + 1)) / factorial(2 * n + 1);
}

这也使其他读者更清楚代码的意图。

¥This also makes the code's intent much clearer to other readers.

也可以看看