現代的JavaScriptおれおれアドベントカレンダー2017 – 09日目

累乗あるいは(べき)乗。

概要

** です。

“1024” といえばもちろん2の10乗ですが、そういう計算です。

console.log(2 ** 10);  // => 1024

= とくっついてる版もあり。

var n = 2;
n **= 6;
console.log(n);  // => 64

仕様

基本的にはただの累乗です。

で、細かい例外的なところもちゃんと決まってます。まあ普通の内容なんだけど。

NaN ** 01

何かの0乗は1になる、と中学校で教わった記憶があるんですが、その原則は NaN にも適用されます。

console.log(2 ** 0);  // 右辺が 0 なら答えは 1
console.log(NaN ** 0);  // 左辺がNaNでも!

NaN にまつわる計算で答えが NaN にならないの、珍しくない?

ちなみに 0 ** NaNNaN です。

左辺に負数を使う場合

計算順序に注意。カッコつけましょう。

console.log((-2) ** 3);  // => -8
console.log( -2  ** 3);  // SyntaxError

エラーメッセージはこんな感じでした。

  • Chrome: Uncaught SyntaxError: Unexpected token **
  • Edge: Invalid unary operator on the left hand side of exponentiation (**) operator
  • Firefox: SyntaxError: unparenthesized unary expression can’t appear on the left-hand side of ‘**’
  • Safari: SyntaxError: Unexpected token ‘**’. Amiguous unary expression in the left hand side of the exponentiation expression; parenthesis must be used to disambiguate the expression.

Safariなげえ。

ES2016

ES2015 (ES6) じゃなくてその翌年のES2016で追加されました。

その他

Math.pos()

も同じ機能です。

console.log(Math.pow(2, 10));  // => 1024

内部的に ** を実行しているので、 NaN の扱いとかも全部一緒です。

演算子の優先順位

って仕様書でexpressionの定義見ながらじわじわ探す感じ? MDNだと単項演算子より下位にあるんだけど、 -2 ** 2 がエラーになるあたり、同点だったりしない?

ExponentiationExpressionの定義はこう。同じ、だよね?

ExponentiationExpression[Yield]:
    UnaryExpression[?Yield]
    UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]

参考