JavaScriptの練習をしてみた【基本文法:演算子編】

JavaScript

この記事では,JavaScriptの基礎文法として,演算子を学習します.

演算子とオペランド

まず,用語の確認をします.

演算子とは,「オペランドに作用するもの」です.以下の例を見てみましょう.

let a;

a = 1 + 2; // オペランド 1 と 2に演算子 + が作用している

console.log(a);

この出力は 3 になります.

2行目に注目してください.この場合,演算子は加算「+」です.

この演算子は,1 と 2に作用して,足し算をしています.つまり,1 と 2がオペランドです.

ちなみに,この例のように2つのオペランドに作用する演算子を二項演算子と言います.

基本的な数値演算子

以降で,以下の演算子について説明します.

・加算演算子「+」

・減算演算子「-」

・乗算演算子「*」

・除算演算子「/」

・剰余演算子「%」

・べき乗演算子「**」

・インクリメント演算子「++」

・デクリメント演算子「–」

加算演算子「+」

数字に対しては,単に数字の足し算になります.

1 + 2; // >> 3

ちなみに,文字列に対しては,文字列を連結します.

"Hello" + "World"; // >> HelloWorld

減算演算子「-」

数字に対しては,単に数字の引き算になります.

3 - 1; // >> 2

文字列に対しては減算演算子は使えません.値はNaN(Not a Number)になります.

"Hello" - "World"; // >> NaN

乗算演算子「*」

数字に対しては,単に数字の掛け算になります.

2 * 3; // >> 6

文字列に対しては乗算演算子は使えません.値はNaNになります.

"Hello" * "World"; // >> NaN
"Hello" * 3; // >> NaN

除算演算子「/」

数字に対しては,単に数字の割算になります.

割られる数 / 割る数です.「÷」と同じです.

6 / 3; // >> 2

割り切れない場合は,少数で値が出ます.

2 / 3; // >> 0.6666666666666666

文字列に対しては除算演算子は使えません.値はNaNになります.

"Hello" / "World"; // >> NaN
"Hello" / 3; // >> NaN

剰余演算子「%」

剰余演算子は,余りを返します.

8 % 3; // >> 2

べき乗演算子「**」

べき乗演算子は,作用することでオペランドのべき乗を返します.

2 ** 3; // >> 8

インクリメント演算子「++」

インクリメント演算子は,数値を+1します.

let a = 2;
a++; // 値を+1する
console.log(a); // >> 3

インクリメント演算子++は,オペランドの前に置くか,後に置くかで処理の順番が異なります.

++を前に置くと,先に+1します.

let a = 2;
console.log(++a); // >> 3

一方で,後に置くとaを返した後に+1されます.

let a = 2;
console.log(a++); // >> 2
console.log(a); // >> 3

デクリメント演算子「–」

デクリメント演算子は,数値を-1します.インクリメント演算子と同じで,オペランドの前に置くか後に置くかで処理が異なります.

let a = 2;
console.log(a--); // >> 2
console.log(a); // >> 1

let b = 2;
console.log(--b); // >> 1
console.log(b); // >> 1

比較演算子

等価演算子「==」

オペランドを比較して,等しい時はtrue,等しくない場合はfalseを返します.

console.log("Hello" == "Hello"); // >> true
console.log("Hello" == "Good"); // >> false
console.log(1 == 1); // >> true
console.log(1 == 2); // >> false

オブジェクトを比較する場合は,その参照が一致している場合にのみtrueを返します.つまり,オブジェクトの中身の値が一致していても,falseになります.

const objA = {"key" : "value"}
const objB = {"key" : "value"}

console.log(objA == objA); // >> true
console.log(objA == objB); // >> false

等価演算子の欠点

等価演算子は比較するオペランドが異なるデータ型のとき,「同じ型となるように」型変換をしてから比較しまいます.

console.log(1 == "1"); // >> true
console.log(0 == false); // >> true

しかし,数字の1と文字列の”1″を比較したいときがあります.そのような場合は,以下の厳密等価演算子を使います.

厳密等価演算子「===」

厳密等価演算子では,値だけでなくデータ型も同じ時にのみ,trueを返します.

console.log(1 === 1); // >> true
console.log(1 === "1"); // >> false
console.log(0 === false); // >> false

プログラミングするときは,なるべく厳密等価演算子を使うことでミスを減らすことができます.

不等価演算子「!=」

オペランドを比較し,等しくない場合は true,等しい場合は false を返します.

console.log("Hello" != "Hello"); // >> false
console.log("Hello" != "Good"); // >> true
console.log(1 != 1); // >> false
console.log(1 != 2); // >> true

console.log(1 != "1"); // >> false
console.log(0 != false); // >> false

先ほどの等価演算子と同じように,不等価演算子では数値の1と文字列の”1″は等しいと判定されるため,falseとなります.

厳密不等価演算子「!=」

console.log("Hello" !== "Hello"); // >> false
console.log("Hello" !== "Good"); // >> true
console.log(1 !== 1); // >> false
console.log(1 !== 2); // >> true

console.log(1 !== "1"); // >> true
console.log(0 !== false); // >> true

不等号演算子「>,<,>=,<=」

不等号演算子は,オペランドの大小を比較してそれが正しい比較の場合は true,そうでない場合は false を返します.

console.log(1 < 2); // >> true
console.log(2 > 1); // >> true

console.log(1 > 2); // >> false
console.log(2 < 1); // >> false

console.log(1 <= 1); // >> true
console.log(1 >= 1); // >> true

console.log(1 >= 1); // >> true
console.log(1 <= 1); // >> true

この比較においても,暗黙的に型変換が行われてから比較されます.

例えば,

console.log("Hello" >= 1); // >> false

はfalseになりますが,以下はtrueになります.

console.log("2" >= 1); // >> true

また,以下もtrueになります.

console.log("Hello" >= "Hello"); // >> true

論理演算子

AND演算子「&&」

イメージとしては「A && B 」で「A が true かつ B が true のときのみ true を返す」ものかと思われますが,正式には「A が true のときに B を返し,Bが false のときには A を返す」ものです.

console.log(true && true); // >> true
console.log(false && true); // >> false
console.log(false && false); // >> false

console.log(true && "B"); // >> B
console.log("A" && false); // >> false
console.log("A" && true); // >> true

つまり,AND演算子&&では真偽値以外も返します.ちなみに,最後の「”A” && true」がtrueになるのは”A”がBooleanで判定するとtrueだからです.

console.log(Boolean("A")); // >> true

つまり,AやBの判定は真偽値で行われ,返す値はそのままということになります.

OR演算子「||」

OR演算子は,「A || B 」というように使いますが,「A が true または B が true のときに true を返す」ものではなく,「A が true なら A を返し,A が false なら B を返す」ものです.

console.log(true || true); // >> true
console.log(false || true); // >> true
console.log(false || false); // >> false

console.log(true || "B"); // >> ture
console.log(false || "B"); // >> B
console.log("A" || false); // >> A
console.log("A" || true); // >> A

ビット演算子

ビット演算は,あまり使わないひとが多いかもしれませんが,簡単に紹介しておきます.

簡単にビットについて復習しておくと,

例えば,10進数の3を4ビットで書くと,0011であり,8を4ビットで書くと,1000で,10を4ビットで書くと1010です.

この10進数から2進数への変換については,別途で調べてみてください.

ビット論理積「&」

ビット演算子を使うときは,オペランドはビットとして変換された後,演算が扱われます.

例えば,「3 & 10」は「0011 & 1010」はという意味になります.論理積は,各ビットごとに見たときに,どちらも1のときに1になるビットを返します.つまり,0011 & 1010の値は0010になります.出力は10進数なので,2(=0010)が出力されます.

console.log(3 & 10); // >> 2

オペランドを陽に2進数で書いた場合も,出力は10進数になります.

console.log(0b0011 & 0b1010); // >> 2 (0b0010とは出力されない)

ビット論理和「|」

先ほどと同じく,両側のオペランドをビットとして判定し,論理和を取ります.論理和は,各ビットのどちらかが1になったら1になるようなビットを返します.

console.log(3 | 10); // >> 11
console.log(0b0011 | 0b1010); // >> 11

0011と1010の論理和は1011=11です.

ビット排他的論理和「^」

排他的論理和は,各ビットが 1 と 0 のペアのときに 1 となるビットを返します.

console.log(3 ^ 10); // >> 9
console.log(0b0011 ^ 0b1010); // >> 9

0011 と 1010 の排他的論理和は 1001 = 9 です.

ビット否定「~」

ビット否定は,各ビットを反転させ,1の補数として返します.

4ビットで見ると 0011(=3) の反転は 1100 ですが,これは負の2進数としては -4 になります.

console.log(~3); // >> -4
console.log(~0b0011); // >> -4

ちなみに,~xのは-(x+1)になる性質があります.

左シフト「<<」

「A << B」で,AをBビットだけ左にシフトします.

// 3を2ビット左にシフトする
console.log(3 << 2); // >> 12
console.log(0b0011 << 2); // >> 12(=1100)

右シフト「>>」

「A << B」で,AをBビットだけ右にシフトします.

console.log(10 >> 2); // >> 2
console.log(0b1010 >> 2); // >> 2(=0010)

ゼロ埋め右シフト演算子「>>>」

右シフト「>>」と同じくビットを右にシフトしますが,右シフト「>>」の場合は最上位ビットは元の最上位ビットをコピーする一方,ゼロ埋め右シフト演算子「>>>」では0で埋めるため,結果がことなる場合があります.

console.log(-4 >> 2); // >> -1
console.log(0b1111_1111_1111_1111_1111_1111_1111_1100 >> 2); // >> -1
// 1111_1111_1111_1111_1111_1111_1111_1111

console.log(-4 >>> 2); // >> 1073741823
console.log(0b1111_1111_1111_1111_1111_1111_1111_1100 >>> 2); // >> 1073741823
// 0011_1111_1111_1111_1111_1111_1111_1111

代入演算子「=」

代入演算子の基本的な機能は変数に値を代入することです.

let a = 3;
console.log(a); // >> 3

代入演算子の別の機能として,これまで紹介した演算子と合わせて使うことで,「演算子を変数に作用して代入する」ことをまとめて行えます.

例えば,加算演算子「+」と合わせて使うと,以下のようになります.

let a = 3;
a += 4; // a = a + 4 と同じ意味
console.log(a); // >> 7

乗算演算子「*」なら,以下のようになります.

let a = 3;
a *= 4; // a = a * 4 と同じ意味
console.log(a); // >> 12

括弧を使おう

最後に,括弧()を使おうという話をしておきます.

演算子を複数作用させるとき,自分が意図しない順番で作用する可能性があります.

そんな時は,括弧を付けることで,その部分から処理を行ってくれます.

以下は,同じオペランドの並びでも返り値が異なる結果になる例です.

let a;
a = 4 * 3 / 2 + 5;
console.log(a); // >> 11

let b;
b = 4 * 3 / (2 + 5);
console.log(b); // >> 1.7142857142857142

数値計算だけでなく,論理演算のときも,括弧を付けることをおすすめします.括弧の順番で,結果がことなります.

let c;
c = (true && false) && (true || true);
console.log(c); // >> false

let d;
d = true && (false && true) || true;
console.log(d); // >> true

次回は,関数について学習します.

参考:

演算子 · JavaScript Primer #jsprimer
JavaScriptにおける演算子についてを紹介します。演算子は記号で表現されるため、検索しにくいです。この章では主要な演算子をまとめて紹介しています。知らない演算子が出てきたときに読み直せばよいため、すべてを1つずつ読む必要はありません。

コメント

タイトルとURLをコピーしました