JavaScriptなどのプログラミング言語では様々な演算を通して処理を行います。
数値演算はもちろんのこと、値を検証するための関係演算や論理演算といったものもあり、どれも重要な基礎知識です。
複雑な処理を学ぶためには必ず必要となる基礎知識ですので、確実に身につけておきましょう!

JavaScriptのスキルを身につけてWebエンジニアとして活躍したいなら、約15.5万の講座の中から自分に合ったものを探せるこちらのサービスがおすすめです。
習得したいスキルに合わせてプロのエンジニアが解説する動画で効率的な学習ができます!
フロントエンドエンジニアになりたい人の Webプログラミング入門

JavaScriptにおける演算

プログラミングにおいては、様々な演算を扱うことになります。
演算の中には、変数に対して値を代入する代入演算、数値型同士に対して数学的な計算を行う数値演算、真偽値による判定を行うための関係演算論理演算、2進数特有の処理を行うためのビット演算があります。

こういった演算の基礎をしっかり身につけておくことで、様々な処理を実現することができます。

演算では、どのような操作を行うのかを指定するための記号と、対象となるデータが必要となります。
データに対して操作を行う記号を演算子(オペレータ)、その左右にある計算対象を被演算子(オペランド)といいます。

    100          +          20
(オペランド) (オペレータ) (オペランド)

代入演算

変数の処理において最もよく用いる操作のひとつは代入です。
代入演算子にはイコール記号( = )を用いますが、これは左右が等価であることを表しているわけではないので注意が必要です。

イコールの左側が対象となる変数で、右側が代入したい値になります。

let score = 100;

このコードでは、scoreという変数に100という数値型(Number)のデータが代入されます。

数値演算

JavaScriptで数値型(NumberやBigInt)同士の数値演算を行うときには、算術演算子を用います。
こちらはまさに計算機に当たる、最もわかりやすい演算処理ではないでしょうか。

四則演算

四則演算に使用する算術演算子はそれぞれ、以下の通りです。
注意するべきなのは、乗算では×ではなくアスタリスク( * )を用い、除算では÷ではなくスラッシュ( / )を用いる点です。

20 + 10;    // 加算

100 - 40;   // 減算

2.5 * 5;    // 乗算

100 / 9;    // 除算

小数を扱う場合に正数部や小数部が0の場合はその部分を省略することもできます。
以下はそれぞれ0.8と3.0の加算を意味しています。

.8 + 3.;

また数値を直接使用するだけではなく、数値型のデータを格納した変数同士をオペランドに取ることもできます。

let a = 10;
let b = 30;
let sum = a + b;

剰余とべき乗

剰余演算は除算の余りを求める演算で、パーセント記号( % )を用います。
除算演算と剰余演算を合わせることで商とその余りを得ることができます。

べき乗演算は左側のオペランドを右側のオペランドの回数だけ掛け合わせます。
オペレータは**で左側のオペランドが底、右側のオペランドが指数となります。

421 % 5;    // 剰余演算

2 ** 5;     // べき乗演算

インクリメントとデクリメント

JavaScriptの数値演算においては、 変数に対してその変数自身を利用した演算を行うという操作が多用されます。
以下の例では、変数xを宣言した時点ではその値は3ですが、xに5を足したものを再度xに代入しているため最終的には8となります。

let x = 3;
x = x + 5;

このような処理はプログラムの中で何か特定の挙動をカウントしたい場合や反復処理などによく用います。
頻出のコードのため短縮記法が存在し、演算子と代入演算子を並べることで利用することができます。
以下の加算、減算演算子以外にも乗算や除算、剰余演算、べき乗演算などでもこの記法が使えます。

let num = 10;

num += 1;    // num = num + 1
num -= 1;    // num = num - 1
num *= 2;    // num = num * 2
num /= 2;    // num = num / 2

さらに変数に対して1を加える、または1を減ずる演算の登場頻度は非常に多くなっています。
そこで用意されているのが、インクリメント・デクリメント演算子です。

インクリメント演算子+記号を2つ並べたものです。
取ることのできるオペランドは1つのみで、オペランドに対して1を加えた値を返します。

デクリメント演算子-記号を2つ並べたものです。
取ることのできるオペランドは1つのみで、オペランドに対して1を減じた値を返します。

インクリメント・デクリメント演算子は、オペランドの前に付けるか後ろに付けるかによって若干挙動が変化します。
オペランドの前に付けた場合は、その処理が実行される前に加減算が行われますが、オペランドの後に付けた場合は処理の実行後に加減算が行われます

let cnt = 0;

// インクリメント : cnt = cnt + 1
cnt++;
++cnt;

// デクリメント  : cnt = cnt - 1
cnt--;
--cnt;

指数の演算

指数表現は、極端に大きいか小さい数値を扱うときに使用します。
eの左側は仮数、eの右側は指数(指数の底は10)で以下のような関係になっています。

$ (仮数)e (指数) = (仮数) \times 10 ^{(指数)} $

5.4e8 + 4.1e6;    // = 544100000

本気でWebエンジニアを目指すなら、現役で活躍する講師の現場で使える技術を学べるこちらの講座がおすすめです。
コミュニティマネージャーとの面談から理想のキャリアと現状に合わせた、自分専用のコースを組み立てることができます。
まずは無料のWeb説明会に参加してみましょう!
ゼロから人気のWebスキルを学ぶなら【Cucua】

関係演算

関係演算はオペランド同士の関係を表すために用いられ、結果は数値ではなく真偽値(ブーリアン)となります
オペランド間にオペレータの指定した関係が成立していれば真(true)、成立していなければ偽(false)という判定を行う演算になります。

等価・不等価演算

左右の値が等価である(または等価でない)ことを判定するための演算子です。
通常の数学的な感覚でいくとイコール記号(=)を使いたくなるのですが、JavaScriptにおいてこの記号は代入を意味します。
プログラムにおける等価演算には=====といった記号を、また不等価演算には!=!==といった記号を用います。

基本的には厳密な等価演算子(===)・不等価演算子(!==)を用いるようにしましょう。
曖昧な等価演算子(==)・不等価演算子(!=)を多用してしまうと、プログラムが予想外の挙動をする可能性があります。

曖昧な等価演算子・不等価演算子

==は曖昧(抽象的)な等価演算子で、型を考慮せずに左右の値が等しいかをチェックします。
例えば、以下のように数値型と文字列型で型は違っても値は等しいと判定されます。

let x = 100;
x == 100;      // true
x == '100';    // true

!=は曖昧(抽象的)な不等価演算子で、等価演算子とは反対の結果を返します。

let x = 20;
x != 10;      // true
x != '20';    // false

厳密な等価演算子・不等価演算子

===は厳密な等価演算子で、値が同じであっても型が異なっていれば不等価であると判定されます。
例えば、以下のように数値型と文字列型で型は違うので値は異なると判定されます。

let x = 100;
x === 100;      // true
x === '100';    // false

!==は厳密な不等価演算子で、等価演算子とは反対の結果を返します。

let x = 20;
x !== 10;      // true
x !== '20';    // true

比較演算

比較演算では左右の値を比較して、条件を満たしていれば真(true)、満たしていなければ偽(false)を返します。
感覚的にわかりやすい部分だと思いますので、簡単に紹介します。

let value = 200;

value > 100;     // true
value < 150;     // false
value >= 200;    // true
value <= 500;    // true

論理演算

論理演算では論理演算子を使用して、複数条件(命題)の組み合わせを考えることができます。

論理和(OR)左右の命題のどちらかが真(true)であれば全体の結果が真(true)となります
オペランドとしては真偽値のみをとり、オペレータは||です。
関係演算の結果は必ず真偽値となるので、オペランドとしてよく用いられます。

論理積(AND)左右の命題の両方が真(true)でなければ全体の結果は真(true)になりません
オペランドとしては真偽値のみをとり、オペレータは&&です。

let answer = 20;

// 論理和
true || false;                 // true
100 > answer || answer > 0;    // true

// 論理積
true && false;                 // false
100 > answer && answer > 0;    // true

また、論理否定(NOT)を用いることで真偽値の結果を反転させることができます。
条件の前にエクスクラメーション(!)をつけることで否定をとります。

!false;           // true
!(100 < 20);    // true

ビット演算

こちらはこれまで紹介してきた演算に比べて少しマニアックな内容となっており、使用頻度も低いです。
どのようなことができるのかを簡単に把握しておきましょう。

10進法以外の表記法

そもそも10進法とは、私たちの日常に最も根付いている数字の扱い方です。
10進法を形式的に表現すると、10区切りで数字をひとまとまりにし位取りを行う方法のことを指します。
言い換えると、0~9までの10種類の数値使用して1桁を表現するということになります。

数字をひとまとまりにする基準となる数字のことを基数といいます。
10進法であれば基数は10になります。
また、10進法を使用して表現した数字を10進数といいます。

時間の考え方では、「秒」や「分」は60でひとまとまりにされる(上位の単位に変換される)ので、60進法といえます。
さらに「時間」は24進法、「日」は365進法となっています。

コンピュータ内部においては、オンとオフの2つの信号のみを取り扱っています。
これを数字に置き換えると基数を2とした2進数、つまり0と1だけで表現することができます。
しかし2進数ではひとまとめにする量が少ないため、桁数が非常に多くなってしまいます。
例えば、Aというたった1文字を表現するのにも、2進数では以下のように非常にわかりにくくなってしまいます。

0b00000000    //
0b00011000    //    **
0b00011000    //    **
0b00011000    //    **
0b00011000    //    **
0b00100100    //   *  *
0b00100100    //   *  *
0b00100100    //   *  *
0b00100100    //   *  *
0b01111110    //  ******
0b01000010    //  *    *
0b01000010    //  *    *
0b01000010    //  *    *
0b11100111    // ***  ***
0b00000000    //
0b00000000    //

そこで2の累乗を基数とした8進数や16進数を利用することも多々あります(2進数との相互換算が容易なためです)。

JavaScriptで10進数以外の数値を扱う方法は簡単です。
使いたい基数に応じた接頭辞(プレフィックス)をつけることで、指定した数値の取り扱い方ができるようになります。

2進数は最初に0b、8進数は最初に0、16進数は最初に0xをつけます。
慣れるまではわかりにくいかもしれませんが、落ち着いて数えていけば難しいことはありません。

10進数2進数8進数16進数
00b0000x0
10b1010x1
20b10020x2
30b11030x3
40b100040x4
50b101050x5
60b110060x6
70b111070x7
80b10000100x8
90b10010110x9
100b10100120xA(0xa)
110b10110130xB(0xb)
120b11000140xC(0xc)
130b11010150xD(0xd)
140b11100160xE(0xe)
150b11110170xF(0xf)
160b100000200x10
170b100010210x11
180b100100220x12
190b100110230x13
200b101000240x14

ビット演算

2進数で表した1桁のことをビットといい、8ビットをまとめた単位をバイトといいます。
ビットを利用した演算のことをビット演算といい、部分的に論理演算によく似ています

先述した通り、基数変換を行うことで2進数以外の数値でも2進数に変換することができます。
そのためJavaScriptではビット演算を2進数以外の基数で行っても、内部的に2進数に変換してから演算が行われます。
ここではわかりやすいように、2進数を使って例を見ていきます。

AND演算では左右のオペランドをビットごとに比較し、両方が1のときにだけそのビットを1にした値を返します
OR演算では左右のオペランドをビットごとに比較し、どちらか一方または両方が1の時にそのビットを1にした値を返します
XOR演算では左右のオペランドをビットごとに比較し、値が異なる場合にだけそのビットを1にした値を返します
NOT演算ではビットを反転した値を返します

// AND演算
0b11110000 & 0b00110011;    // 0b00110000

// OR演算
0b11110000 | 0b00110011;    // 0b11110011

// XOR演算
0b11110000 ^ 0b00110011;    // 0b11000011

// NOT演算
~0b11110000;                // 0b00001111

シフト演算

シフト演算では、各ビットをひとつずらします。

左シフト演算では、左側のオペランドのビットを右側のオペランドの数値分だけ左方向にずらします。
また、ずらした分だけビットの右端に0を詰めます。
1ビット分だけ左シフトした数値は、元の数値の2倍になっています。
これは2進法の性質で、10進法で左シフトを行うと元の数値の10倍になることを考えるとわかりやすいと思います。
例えば、10進数の128を左シフトすると1280となり10倍になりますよね。

右シフト演算では、 左側のオペランドのビットを右側のオペランドの数値分だけ右方向にずらします。
右シフト演算にはシフトした後の最上位ビットの扱い方で、符号付きと符号なしの2種類に分けることができます。
符号付きでは右シフトした後に、元の2進数データの左端のビットとおなじものを詰めます
符号なしでは右シフトした後に、元の2進数データに関係なく0を詰めます
これが符号付きや符号なしに対応している理由については省きますが、詳細が知りたい方は補数について調べてみてください!

// 左シフト演算
0b11110000 << 2    // 0b11000000

// 符号付き右シフト演算
0b11110000 >> 1    // 0b11111000

// 符号なし右シフト演算
0b11110000 >>> 1   // 0b01111000

まとめ

今回はJavaScriptで利用できる各種演算についてみてきました。
演算とは、演算子(オペレータ)により被演算子(オペランド)に対して様々な操作を行い、その結果を得ることを言います。

代入演算では、左側のオペランドに対して右側のオペランドの値を代入します。
数値演算では、左右のオペランドに対して四則演算などの数学的な演算を行います。
関係演算では、左右のオペランドを比較することで条件を満たしているかを真偽値で判定します。
論理演算では、左右のオペランドに真偽値をとりそれらの関係性を評価します。
ビット演算では、2進数のオペランドに対する各種演算を行います。

これらの演算をしっかりと理解しておけば、制御構文や今後のプログラミング学習に役立つこと間違いなしです!

ひとりではなかなかプログラミングの学習が続かない、未経験だから不安が多い、という方はプログラミングスクールを利用してみるのも有効です。
本物のエンジニアに学ぶことで、時間がない方でも最短でスキルを身につけることができます。
現役エンジニアのパーソナルメンターからマンツーマンで学べる

お悩みの方は、まずは無料キャリアカウンセリングにお申込みください。

関連記事

この記事のタグ