SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '**'
L'exception JavaScript "unparenthesized unary expression can't appear on the left-hand side of '**'" se produit lorsqu'un opérateur unaire (parmi typeof
, void
, delete
, await
, !
, ~
, +
, -
) est utilisé sur l'opérande gauche de l'opérateur d'exponentiation sans parenthèse.
Message
SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence (moteur JavaScript basé sur V8) 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)
Type d'erreur
Quel est le problème ?
Cela provient vraisemblablement d'une écriture comme celle-ci :
-a ** b
Ici, l'expression est ambigüe et on ne sait pas si elle devrait être évaluée comme (-a) ** b
ou comme -(a ** b)
. En mathématiques, l'écriture -x2 signifie -(x ** 2)
, et c'est ainsi que de nombreux langages de programmation, comme Python, Haskell, et PHP, gèrent cette évaluation. Mais si la précédence de l'opérateur unaire moins l'emporte sur **
, cela casse la symétrie avec a ** -b
, qui s'évalue sans ambigüité comme a ** (-b)
. Aussi, le langage interdit cette syntaxe et impose d'utiliser des parenthèses d'un côté ou de l'autre pour résoudre l'ambigüité.
(-a) ** b;
-(a ** b);
D'autres opérateurs unaires ne peuvent pas être utilisés sur l'opérande gauche non plus.
await a ** b;
!a ** b;
+a ** b;
~a ** b;
Exemples
Lorsqu'on écrit des expressions mathématiques complexes utilisant l'exponentiation, on peut aboutir à quelque chose comme :
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 '**'
}
Toutefois, le fragment -1 ** n
est illégal en JavaScript. À la place, on utilisera des parenthèses sur l'opérande gauche :
function taylorSin(x) {
return (n) => ((-1) ** n * x ** (2 * n + 1)) / factorial(2 * n + 1);
}
Cela a également l'avantage de rendre le code plus compréhensible et explicite.