Exponentiation means raising a base to an exponent—for example, raising 4 to the third power yields 64. In modern JavaScript you usually express that with the ** operator, or with Math.pow(base, exponent) when you want a function call or need compatibility with very old engines. For more patterns around powers and edge cases, see JavaScript Math.pow and related topics.
This guide covers **, Math.pow, BigInt rules, right-associativity, the unary-minus gotcha, and a couple of edge cases from the spec.
Tested on: all examples in this tutorial were run with Node.js v20.18.2, and the output shown below each snippet is its exact console output.
Quick reference
Use this table for exponentiation javascript: numbers vs BigInt and parsing pitfalls.
| Tool | Numbers | BigInt | Notes |
|---|---|---|---|
x ** y |
Yes | Yes if both are BigInt | Right-associative; unary - needs () on base |
Math.pow(x, y) |
Yes | No (throws on BigInt) | Works on older engines without ** |
1. From repeated multiplication to **
let repeated = 4 * 4 * 4;
let operator = 4 ** 3;
console.log(repeated);
console.log(operator);64
642. Exponentiation (**) and BigInt
The operator is overloaded for number and BigInt (see MDN): if both sides are BigInt, you get a BigInt result. Math.pow, by contrast, only accepts numbers—passing a BigInt throws TypeError.
const big = BigInt(345) ** BigInt(3);
console.log(big);41063625ntry {
console.log(Math.pow(2n, 2));
} catch (e) {
console.log(e.name + ": " + e.message.split("\n")[0]);
}TypeError: Cannot convert a BigInt value to a numbertry {
console.log(2n ** 2);
} catch (e) {
console.log(e.name);
}TypeErrorUse 2n ** 2n (or convert explicitly) when you need BigInt powers.
3. Fractional exponents (still numbers)
console.log(4 ** 3.3);97.00586025666546Floating-point javascript exponent math is approximate, like other Number operations.
4. Negative base: parenthesize
Unary - binds looser than **, so -2 ** 5 is parsed as -(2 ** 5), not (-2) ** 5. Use parentheses on the base when you mean a negative number raised to a power.
console.log((-2) ** 5);-325. Right-associativity (**)
a ** b ** c is a ** (b ** c), not (a ** b) ** c.
console.log(2 ** 3 ** 2);
console.log(2 ** (3 ** 2));
console.log((2 ** 3) ** 2);512
512
646. NaN ** 0 (special case)
console.log(NaN ** 0);1The same quirk applies to Math.pow(NaN, 0) per MDN.
7. Compound assignment (**=)
let x = 2;
x **= 3;
console.log(x);88. Math.pow (numbers only)
console.log(Math.pow(4, 5));
console.log(Math.pow(6, -2));
console.log(Math.pow(-2, 5));1024
0.027777777777777776
-32Math.pow(-2, 5) does not need extra parentheses on the base because the base is a normal function argument, not a unary-expression parsing edge case.
Summary
**is concise and supports BigInt when both operands are BigInt; watch precedence with unary-.**is right-associative: add parentheses when you mean(a ** b) ** c.Math.powis numbers-only; use it when targeting engines without**.NaN ** 0andMath.pow(NaN, 0)yield1by spec.
References
MDN references for the exponentiation operator, Math.pow, and precedence.
