简体   繁体   中英

JavaScript exponentiation unary operator design decision

So I was fooling around with the new exponentiation operator and I discovered you cannot put a unary operator immediately before the base number.

let result = -2 ** 2; // syntax error
let result = -(2 ** 2); // -4
let x = 3;
let result = --x ** 2; // 4

From the documentation on MDN :

In JavaScript, it is impossible to write an ambiguous exponentiation expression, ie you cannot put a unary operator ( + / - / ~ / ! / delete / void / typeof ) immediately before the base number.

In most languages like PHP and Python and others that have an exponentiation operator (typically ^ or ** ), the exponentiation operator is defined to have a higher precedence than unary operators such as unary + and unary - , but there are a few exceptions. For example, in Bash the ** operator is defined to have a lower precedence than unary operators.

I understand this was made an error by design. I don't understand this design decision. Who's really going to be surprised that -x ** 2 is negative? This follows not only other mainstream programming languages but a mathematical notation that has been in common use for hundreds of years and is taught to every high school algebra student.

In Javascript '1'+ 2 is '12' and '1'-2 is -1 but -1**2 raises an error because it could be ambiguous? Help me understand this design decision.

I don't understand this design decision.

Read more about it at https://esdiscuss.org/topic/exponentiation-operator-precedence , https://esdiscuss.org/topic/power-operator-why-does-2-3-throws , https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-09/sept-23.md#exponentiation-operator and https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-09/sept-24.md#exponentiation-operator .

Who's really going to be surprised that -x ** 2 is negative?

Enough people to matter. Some relevant quotes from the above resources:

  • " making ** bind tighter than unary operators would break x**-2 . And making it sometimes tighter and sometimes looser would be too confusing and lead to other opportunities for precedence inversion. " - Waldemar Horwat
  • " Given the conflict between the history of ** in other languages, [and] the general pattern that unary binds tighter than binary, any solution at this point will confuse many people. " - Mark S. Miller
  • " acknowledge the prospect of significant whitespace: -x**2 === -(x ** 2) and -x ** 2 === (-x) ** 2 " - Alexander Jones
  • " The problem is, however rare unary minus before an exponentiation expression may be, the lack of superscript-with-smaller-font sugests that - binds tighter than ** . And indeed apart from dot (a special form whose right operand must be a lexical identifier-name) and square brackets (which isn't an infix operator per se), unary operators bind tighter than binary in JS as in C and other C-derived languages. " - Brendan Eich
  • " For math it seems obvious that -5 2 . But for -5 ** 2 , because of the whitespace around the infix operator. Even without space, - seems to be part of the literal. " - Dave Herman
  • [Regarding programming language precedence], " effectively zero people have an intutition about this from other languages. Agree people have an itutition that ** is the exponentiation operator. But people usually try to avoid dark corners so they never develop an intuition for negative bases. " - Dave Herman

In Javascript '1'+ 2 is '12' and '1'-2 is -1 but -1**2 raises an error because it could be ambiguous?

Well they put considerably more effort in the design of extensions to the language today :-) It's the best solution that they could reach consensus for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM