JavaScript での基本演算 — 数値と演算子

今回は JavaScript での数学的処理についてです。我々の命令を実行するために上手く数値を操作するのにどのように 演算子 や、その他の機能を使用できるのかを見ていきましょう。

前提条件: HTML と CSS の基本についての理解、 JavaScript が何かが分かっていること。
目標: JavaScript での基礎的な数値処理に慣れること。

みんな数学が大好き

まあ、みんなではないですね。好きな人もいれば、九九や長い数字の割り算が出てきてから嫌いになってしまった人もいるでしょう。どちらでもない人も。けれど、数学が生活に必要なものであるということは、否定することは出来ません。特に JavaScript (または同様の言語)のプログラミングを学習しているのなら、なおさらです。数値データを処理したり、計算をしたりすることが多いので、JavaScript に数学的な関数が十分にそろっていることは、驚くことではありません。

この記事ではまず知っておくべき基礎的なものに絞って見ていきます。

数値の種類

プログラミングをしていると、慣れ親しんだ普通の数値ですら難しいと思えるかもしれません。数値と言ってもいくつか種類があり、それぞれ名前を付けて区別しています。

  • 整数 (integer) とは 10、400、-5 といった数値のことです。
  • 浮動小数点数 (float) とは小数以下の数と小数桁を持つ 12.5 や 56.7786543 といった数値のことです。
  • 倍精度浮動小数点数 (double) は浮動小数点数の特殊な型であり、通常の浮動小数点数よりも大きな精度を持ちます (つまりより大きい桁数まで精度を保つことを意味します)。

さらに通常とは異なる数値表現も使います!今まで出てきた数値は 10 を基数 (0 ~ 9 を 1 つの桁として扱う) とした十進数でしたが、他にも以下のようなものがあります。

  • 二進数 — 0 と 1 だけで表現される、コンピューターの最も低レベルな言語です。
  • 八進数 — 8 を基数として、1 桁を 0 ~ 7 で表します。
  • 十六進数 — 16 を基数として、1 桁を 0 ~ 9、a ~ f で表します。もしかしたら CSS の色を設定するときに見たかもしれませんね。

**脳みそが溶けそうだと思う前に、少し待ってください!**まず、この講座では十進数しか扱いません。それに「もしかすれば」ですが、他の数値表現について考える機会は訪れないということだってあり得ます。

さらにちょっといいことを教えましょう。いくつかの他のプログラミング言語とは違い、JavaScript には数値(整数と小数の両方)を表すデータ型が一つしかありません。わかりますか?数値型 (Number) で、これは整数と小数の両方です。これは JavaScript でどんな型の数値を扱おうとも、それらを全く同じように扱うことが可能だということを意味します。

メモ: 実は、JavaScript には 2 つ目の数値型である BigInt があり、これはとても大きな整数に使います。しかしこのコースの目的としては、Number の値だけに関心を持つことにします。

私にとってすべては数字

書き方の復習を兼ねてちょっと数字で遊んでみましょう。以下に示すコマンドを開発者ツールの JavaScript コンソールに入力してみましょう。もちろんこのページの埋め込みコンソールを使っても構いません。

  1. まず、変数を 2 つ宣言して、それぞれ整数と浮動小数点数で初期化してみましょう。そして、変数の名前を入力して、期待通りに値が入っていることを確認してみましょう。

    js
    const myInt = 5;
    const myFloat = 6.667;
    myInt;
    myFloat;
    
  2. 数値には引用符が不要です。次に進む前にもう少し変数の宣言と初期化をしてみてください。

  3. さて、それでは上で入力した 2 つの変数が同じデータ型であるか確認してみましょう。 JavaScript では、typeof という演算子を使用することで、データ型を確認することができます。次の 2 行を入力してみましょう。

    js
    typeof myInt;
    typeof myFloat;
    

    どちらの変数についても "number" という文字が戻ってきましたね。もし、別々の数値型が存在しているとすれば、別々に処理しなければならないので、そう考えるととても簡単に思えますよね!

便利な Number のメソッド

Number オブジェクトは、あなたが JavaScript を使う時すべての基本的な数値を表現するインスタンスですが、その中には、数値を操作するための沢山の便利なメソッドがあります。この記事では、簡単な紹介と基本的な要点だけまとめたいので、詳しくは割愛しますが、この段落を何回か読んだら、オブジェクトリファレンスページに行って、どんなメソッドが使えるのかを勉強するのが良いと思います。

例えば、数値を固定の桁数に丸めるには toFixed() メソッドを使用します。ブラウザーのコンソールに次の行を入力します。

js
const lotsOfDecimal = 1.766584958675746364;
lotsOfDecimal;
const twoDecimalPlaces = lotsOfDecimal.toFixed(2);
twoDecimalPlaces;

数値データ型への変換

たまに、文字列型として格納されている数字で計算ができなくなってしまうことがあります。これは、データがフォーム入力に入力され、input の type が text である場合によく起こります。この問題を解決する方法があります - 文字列の値を Number() コンストラクターに渡すと、同じ値の数値バージョンを返します。

例えば、これらの命令をコンソールに入力してみてください。

js
let myNumber = "74";
myNumber += 3;

答えは 743 です。77 ではありません。 なぜなら myNumber は文字列として定義されているからです。以下の命令で確認することができます。

js
typeof myNumber;

これは以下のようにして修正することができます。

js
let myNumber = "74";
myNumber = Number(myNumber) + 3;

結果は当初の期待通り 77 になります。

算術演算子

算術演算子は JavaScript で計算をするのに使用する最も基本的な演算子です。

演算子 名前 目的
+ 加算 2 つの値を足す。 6 + 9
- 減算 左項より右項の数を引く。 20 - 15
* 乗算 2 つの値を掛ける。 3 * 7
/ 除算 左項の数値を右項で割る。 10 / 5
% 剰余 (モジューロともいう)

左項の数値を右項の数値で割った同じ数の整数に分割した後に残った余りを返します。

8 % 3 (8 を 3 つずつ分けると 2 つに分かれ、 2 が残るので 2 を返す。)

** べき乗 base 数を exponent 乗、つまり、base 数にそれ自身をexponent 回掛けたしたものにします。 5 ** 225 を返します。これは 5 * 5 と同じです。)

メモ: 演算に使用される数のことをオペランドと呼ぶことがあります。

メモ: べき乗が、よく似た動作をする古い Math.pow() メソッドを使って表現されているのを見ることがあるかもしれません。たとえば、 Math.pow(7, 3) では、 7 が基数で 3 が指数であるため、式の結果は 343 になります。 Math.pow(7, 3)7**3 と同じです。

たぶん基本的な数学を教える必要はないでしょうが、ここに出てくる文法を理解しているかをテストしたいと思います。書き方を覚えるため、以下に示す例を開発者ツールの JavaScript コンソールに入力してみましょう。

  1. まずは次のような簡単な例を自分で試してみてください。

    js
    10 + 7;
    9 * 8;
    60 % 3;
    
  2. そして、変数を宣言して初期化し、数を変数に格納します。それから変数を使って計算してみましょう。変数は計算するにあたり、保持している値がそこにあるかのように使えます。例えば次の通り。

    js
    const num1 = 10;
    const num2 = 50;
    9 * num1;
    num1 ** 3;
    num2 / num1;
    
  3. それではさらに難しい計算式を入力してみましょう。

    js
    5 + 10 * 3;
    (num2 % 9) * num1;
    num2 + num1 / 8 + 2;
    

最後の例の中に予想した結果と違う答えがありませんでしたか。次の章でなぜそうなったかを説明してみましょう。

演算子の優先順位

先ほどの計算式の一番最後の例を見てみましょう。 num2 に 50、num1 に 10 が格納されているものとします。(最初はそうでしたよね。)

js
num2 + num1 / 8 + 2;

ある人は、先に「50 + 10 = 60」と「8 + 2 = 10」を先に計算して、その後で「60 ÷ 10 = 6」となるように計算するかもしれません。

けれどもブラウザーは「10 ÷ 8 = 1.25」を先に計算してから「50 + 1.25 + 2 = 53.25」を計算します。

どうしてこうなるのかといえば、演算子には優先順位があるからです。ある演算子は (プログラムのによっては) 他の演算子よりも先に実行されます。JavaScript の演算子の優先順位は算数の授業で教わったものと同じです。つまり、乗算と除算は常に最初に行われ、それから加算と減算が実行されます。(通常の計算は常に左から右に評価されます。)

もし、演算子の優先順位を変更したいならば、先に実行したい部分を括弧 (()) を使って囲みます。もし先ほどの例で 6 が答えになるようにしたいなら次のようにします。

js
(num2 + num1) / (8 + 2);

実際に実行し、結果を見てみてください。

メモ: JavaScript の演算子とその優先順位については演算子の優先順位で確認することができます。

インクリメント演算子とデクリメント演算子

たまに、繰り返し値を足したり引いたりしたいときがあるでしょう。そんなときに便利なのがインクリメント演算子 (++) とデクリメント演算子 (--) です。もう既に、JavaScript の最初の一歩に出てくる「数字当てゲーム」で、ユーザーの残り予想回数を求めるために使用する guessCount 変数に 1 を加えるのに ++ を使用しました。

js
guessCount++;

それでは、コンソールで試してみましょう。ただし、その前に注意点です。この演算子は数値には直接使用できません。変に思えるかもしれませんが、これは対象の値そのものに作用するわけではなく、変数に対して新しい値を代入するのです。次の例はエラーになります。

js
3++;

既に存在する値に対してのみインクリメントすることができます。

js
let num1 = 4;
num1++;

また変なことが起きましたね!上のコードを実行したとき「4」がコンソールに表示されました。これはブラウザーが現在の値を先に返して、その後にインクリメントを実行したためです。もう一度変数を入力してみると、変数がインクリメントされていることがわかります。

js
num1;

それは -- 演算子についても同様です。以下のコードも試してみてください。

js
let num2 = 6;
num2--;
num2;

メモ: 変数の前に演算子を置くことで、ブラウザーにインクリメントまたはデクリメントを先にさせてから値を戻すようにすることもできます。上記の例に戻って今度は ++num1--num2 のように入力してみてください。

代入演算子

代入演算子は変数に値を代入します。すでに一番基本的な = 演算子を何度も使用しています。この演算子は単に左辺に記述された値を右辺に代入します。

js
let x = 3; // x には 3 が入る
let y = 4; // y には 4 が入る
x = y; // x には y と同じ値:4 が入る

ただし、コードを簡潔に効率よく書くための、もっと複雑な方法が用意されています。よく見かけるものを以下に示します。

演算子 名前 目的 同様のコード
+= 加算代入 右辺の値を左辺の変数値に加算してから、新しい値を返す x += 4; x = x + 4;
-= 減算代入 右辺の値を左辺の変数値より減算してから、新しい値を返す x -= 3; x = x - 3;
*= 乗算代入 左辺の変数値に右辺の値を乗算してから、新しい値を返す x *= 3; x = x * 3;
/= 除算代入 左辺の変数値を右辺の値で除算してから、新しい値を返す x /= 5; x = x / 5;

どのように動いているか理解するため、コンソールに上記の例をいくつか入力してみましょう。どの例も、2 行目を入力する前にコードがどのようになるかを予想してから入力しましょう。

ちなみに、どの演算子も右辺には自由に変数を置くことができます。例えば以下のように。

js
let x = 3; // x には 3 が入る
let y = 4; // y には 4 が入る
x *= y; // x は 12 になる

メモ: もっとたくさんの代入演算子がありますが、とりあえず今は基本的なものだけ知っておけばよいでしょう。

アクティブラーニング: canvas のボックスのサイズを変更する

練習として、数値と演算子を使用してボックスのサイズを変更してみましょう。ブラウザーの Canvas API を使用してボックスを描きます。どうやって描くかについて気にする必要はありません。今は計算に集中しましょう。ボックスの幅と高さ (ピクセル単位で) 変数 xy で宣言しています。最初は 50 になっています。

新しいウィンドウで開く

上の編集可能なコードには、変更すべき 2 つの行にコメントが書かれています。その行を適切な演算子および値を用いて変更し、拡大縮小させてください。それではやってみましょう。

  • ボックスの幅を 50px としたまま x の値を求める行を変更してください。ただし、50 を 43 と 7、算術演算子を一つ使って演算によって求めてください。
  • ボックスの高さを 75px になるよう y の値を求める行を変更してください。ただし、75 を 25 と 3、算術演算子を一つ使用して演算によって求めてください。
  • ボックスの幅を 250px になるように x の値を求める行を変更してください。ただし、250 は 2 つの数値と、剰余演算子を使用して演算によって求めてください。
  • ボックスの高さを 150px になるように y の値を求める行を変更してください。ただし 150 は 3 つの数値と減算演算子および除算演算子を使用して演算によって求めてください。
  • ボックスの幅が 200px になるように x の値を求める行を変更してください。ただし 200 は 4 と代入演算子を一つ使用して演算によって求めてください。
  • ボックスの高さが 200px になるように y の値を求める行を変更してください。ただし 200 は 50 と 3 と乗算演算子、加算演算子を使用して求めてください。

コードを完全に壊してしまっても大丈夫です。いつでもリセットボタンを押すことで何度でも最初から実行できます。上の問題に全問正解したら、もう少し遊んでみてもいいですし、自分で問題を作ってみてもいいですね。

比較演算子

ときには、true または false を判定し、その結果により動作を変更したいと思う時があるでしょう。そのようなことをするために比較演算子を使用します。

演算子 名前 目的
=== 厳密等価 右辺と左辺が厳密に同一の値であるかを判定します 5 === 2 + 4
!== 厳密不等価 右辺と左辺が厳密に同一の値ではないことを判定します 5 !== 2 + 3
< 小なり 左辺の値が右辺の値より小さいこととを判定します 10 < 6
> 大なり 左辺の値が右辺の値より大きいことを判定します 10 > 20
<= 以下なり 左辺の値が右辺の値以下であることを判定します 3 <= 2
>= 以上なり 左辺の値が右辺の値以上であることを判定します 5 >= 4

メモ: もしかしたら ==!= といった演算子を同値かどうかの判定に使用する人を見かけることがあるかもしれません。これらも JavaScript の有効な演算子ですが、===!== とは異なります。前者のバージョンは値が同様であるかを判定しますが、データ型が同様かは判定しません。後者は厳格なバージョンで値とデータ型の両方を判定します。厳格なバージョンはエラーとなることが少ないため後者を使用することをお勧めします。

もし、これらの値をコンソールに入力したら、すべて true または false の値を返します。これは前回の記事で言及した、真偽値です。真偽値はとても便利です。コードで判断をすることを可能にしてくれます。また選択肢を選ぶときには毎回使うことになるでしょう。例えば以下のような場合に。

  • 機能が使用可能かどうかに応じてボタンに表示するテキストを変更する
  • 負けた時にゲームオーバー、勝った時に勝利のメッセージを表示する
  • 時候のあいさつを時期に応じて表示する
  • 選択されたズームレベルに応じて地図を拡大する

後の記事にて、条件文でどのようにロジックをコーディングするのかを見ていきます。とりあえずの簡易な例で見てみましょう。

html
<button>起動する</button>
<p>マシンは停止中です。</p>
js
const btn = document.querySelector("button");
const txt = document.querySelector("p");

btn.addEventListener("click", updateBtn);

function updateBtn() {
  if (btn.textContent === "起動する") {
    btn.textContent = "停止する";
    txt.textContent = "マシンが起動しました!";
  } else {
    btn.textContent = "起動する";
    txt.textContent = "マシンは停止中です。";
  }
}

新しいウィンドウで開く

等価演算子が updateBtn() 関数の中で使用されていることがわかりますね。今回の場合は数値が同じ値かを判定するためには使用していません。ボタンの内容として設定されている文字列が、特定の文字列であるかどうかを比較しています。ただし、原理的には同じ働きです。もしボタンに「起動する」と書かれていれば、押されたときにボタンのラベルが「停止する」に代わります。もしボタンに「停止する」と書かれていれば、再度入れ替わって元に戻ります。

メモ: 2 つの状態を行き来するこのような操作を一般的にトグルといいます。スイッチの ON/OFF のように、ある状態がもう一つの状態にトグル (切り替え) するといいます。

スキルをテストしよう!

この記事の終わりまで到達しましたが、最も大事な情報を覚えていますか?移動する前に、この情報を取得したかのテストを見ることができます — スキルテスト: 演算 を見てください。

まとめ

この記事では、 JavaScript で数字について知っておくべき基本的な情報について、とりあえず扱いました。 JavaScript を学習していく中で、数値はすべて何度も使用することになるので、今のうちに取得しておくのはよい考えです。もしあなたが数学を楽しめない人であれば、この章はかなり短かったので安心してください。

次の章では文字列と、文字列を JavaScript で操作する方法について見ていきます。

メモ: もし数学が好きで、 JavaScript にどう実装されているかをもっと知りたいのであれば、MDN の JavaScript のメインの章に詳細がたくさん載っています。まずは数値と日付式と演算子辺りの記事から読むのがいいでしょう。