現代的JavaScriptおれおれアドベントカレンダー2017 – 09日目
累乗あるいは冪乗。
概要
**
です。
“1024” といえばもちろん2の10乗ですが、そういう計算です。
console.log(2 ** 10); // => 1024
=
とくっついてる版もあり。
var n = 2; n **= 6; console.log(n); // => 64
仕様
基本的にはただの累乗です。
で、細かい例外的なところもちゃんと決まってます。まあ普通の内容なんだけど。
NaN ** 0
は 1
何かの0乗は1になる、と中学校で教わった記憶があるんですが、その原則は NaN
にも適用されます。
console.log(2 ** 0); // 右辺が 0 なら答えは 1 console.log(NaN ** 0); // 左辺がNaNでも!
NaN
にまつわる計算で答えが NaN
にならないの、珍しくない?
ちなみに 0 ** NaN
は NaN
です。
左辺に負数を使う場合
計算順序に注意。カッコつけましょう。
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]
参考
- ECMAScript® 2016 Language Specification
- 12.6Exponentiation Operator
- 12.7.3.4Applying the ** Operator
- 20.2.2.26Math.pow ( base, exponent ) …
Math.pow()
。この中で**
を実行、ということになった
- ECMAScript 2015 Language Specification – ECMA-262 6th Edition … 前の仕様。まだ
**
がない - Operator precedence – JavaScript | MDN … 演算子の優先順位