この記事は 夏のブログリレー 31 日目の記事です。
こんにちは、24B のりすりすです。
突然ですが、タイトルの問題を考えてみてください。厳密な問題文も書いておきます。
console.log(-3 ** 2); を、ECMAScript 2016 以降に準拠した JavaScript 実行環境 (Node.js v24 など) でそのまま実行すると、どうなるでしょう?以下、補足です。
- 数学では であり、 です。
- JS で
console.log(-(3 ** 2));を実行すれば-9が、console.log((-3) ** 2);を実行すれば9が出力されます。 - Python で
print(-3**2)を実行すると-9と出力されます。
では、結果を予想してみましょう!
大ヒント! (クリックで開く)
MDN の優先順位表 によれば、単項マイナス演算子の優先順位はべき乗演算子の優先順位よりも高いです。
↓ スクロールして正解発表 ↓
数式的には -9、演算子の優先順位的には 9 が出力されそうで、迷った方も多いと思います。
お手元に JS の実行環境がある方は、実際に試してみましょう。ブラウザーの DevTools の Console から実行してもよいですし、手元のターミナルで Node.js の REPL を開いて実行してもよいです。
さて、正解発表といきましょう。
$ node
Welcome to Node.js v24.19.0.
Type ".help" for more information.
> console.log(-3 ** 2);
console.log(-3 ** 2);
^^^^^
Uncaught:
SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence
>
はい。びっくりしましたか? 正解は、
でした。実はこれ、-9 でも 9 でもなく、構文エラーになるのです。紛らわしい所をあらかじめ防いでいてくれてありがたいですね!
ヒントは優先順位は単項マイナス演算子の方が上と書いてたのにどういうことやと思いましたか? 実は MDN では「左辺は優先順位 14 になることはできません。」と補足があり、またべき乗のページでは以下のように説明されています。
PHP や Python など、べき乗演算子 (
**) を持つほとんどの言語では、べき乗演算子は単項演算子(単項+や単項-など)よりも優先順位が高いと定義されていますが、いくつかの例外があります。例えば、Bash では**演算子は単項演算子よりも優先順位が低いと定義されています。JavaScript では、あいまいなべき乗式を記述することはできません。 つまり、基数の直前に単項演算子(優先順位 14、
+/-/~/!/++/--/delete/void/typeof/await)を置くことはできません。 これを行うと、SyntaxError が発生します。例えば、
-2 ** 2は Bash では 4 ですが、それ以外の言語(Python など)では -4 です。これは JavaScript では演算子が曖昧であるため、無効な操作です。意図を明確にするには、いずれかの辺を括弧で囲む必要があります。例えば-(2 ** 2)のようにします。
この仕様を既に知っていたという人は、是非コメントで伝えてください。実は過去に Twitter で同じクイズを出題していたのですが、245 票のうち正解していたのは 38 票だけでした。
JavaScript クイズ!
— 🐿りすりす/TwoSquirrels🐿 (@TwoSquirrels) November 14, 2024
console.log(-3 ** 2);
の出力は?
こういうプログラミング言語に関するマニアックな知識って、面白いですよね。そんな面白さを皆さんにも共有したくて、クイズ形式の記事にしてみました。
最後までお読みいただきありがとうございました。それでは、また次の記事で会いましょう! またね!
明日のブログリレーの投稿者は @uni_kakurenbo です。お楽しみに!