The Exponentiation Operator in JavaScript
Now that the ECMAScript 2015 (ES6) specification is finished, it's time to look at what ECMAScript 2016 (ES7) might look like. One of the features that's very likely to make it into this release is the exponentiation operator. As of today (November 24th, 2015), it's a state-3 proposal and therefore called a "candidate", so it's likely we're going to see it included in the ECMAScript 2016 specification.
#The Exponentiation Operator
If you want to do computations with powers in today's JavaScript, you can use the Math.pow
function. Pass it a base and an exponent and you'll get back the result of raising base to the power exponent:
const square = x => Math.pow(x, 2);
const cube = x => Math.pow(x, 3);
square(4); // 16
cube(3); // 27
With the exponentiation operator, the power computation can be more succinctly expressed using infix notation. Similar to other languages such as Python or F#, **
is used to denote the operator. It accepts base on its left-hand side and exponent on its right-hand side, respectively:
const square = x => x ** 2;
const cube = x => x ** 3;
As with other arithmetic operators, there exists an assignment operator **=
for the exponentiation operator. The exponentiation assignment x **= y
is short for x = x ** y
, as you might expect:
let value = 5;
value **= 2;
// value: 25
#The Exponentiation Operator in TypeScript
Starting with TypeScript 1.7, you can use the exponentiation operator in your TypeScript files. Here's the cube
function from above with an explicit type annotation added:
const cube = (x: number) => x ** 3;
The downleveling of **
is pretty straightforward. When targeting ECMAScript 5, the TypeScript compiler will emit the following code:
var cube = function (x) {
return Math.pow(x, 3);
};
When targeting ECMAScript 2015 (ES6), the compiler will neither rewrite the const
declaration nor the arrow function, but it will still replace **
by a call to Math.pow
because ECMAScript 2015 doesn't support the exponentiation operator:
const cube = x => Math.pow(x, 3);
#The Exponentiation Operator in Babel
Similarly, the exponentiation operator can be transpiled by Babel as well. By default, however, Babel doesn't support stage-3 proposals (or proposals at a lower stage). You will have to install one of the available plugins to get support for the syntax and transpilation of language features that are not yet standardized:
- babel-plugin-transform-exponentiation-operator: only the operator itself
- babel-preset-stage-0: all supported feature proposals at stage 0, 1, 2, or 3
- babel-preset-stage-1: all supported feature proposals at stage 1, 2, or 3
- babel-preset-stage-2: all supported feature proposals at stage 2 or 3
- babel-preset-stage-3: all supported feature proposals at stage 3
Note that the presets for all proposals at a certain stage also include all proposals that have already progressed to a higher stage.
Here's our cube
function again, using the exponentiation operator:
const cube = x => x ** 3;
And this is the downleveled code that Babel emits:
"use strict";
var cube = function cube(x) {
return Math.pow(x, 3);
};
#Conclusion
If you're using Babel or TypeScript >= 1.7, you can start using the **
operator today. A stage-3 proposal, the exponentiation operator is very likely to be included as part of ECMAScript 2016. In case the proposal should be withdrawn (which is almost impossible at this stage), it's trivial to change all usages of **
into their Math.pow
equivalent, so there's no risk involved.