
javascript 基本文法3
公開日: 2025/2/28
javascript基本文法について
1. 演算子

演算子はよく利用する演算処理を記号などで表現したものです。
たとえば、足し算をする + も演算子の一種です。これ以外にも演算子には多くの種類があります。
演算子は演算する対象を持ちます。
この演算子の対象のことを被演算子(オペランド)と呼びます。
次のコードでは、+演算子が値同士を足し算する加算演算を行っています。
このとき、+演算子の対象となっている1と2という2つの値がオペランドです。
1 + 2;
このコードでは+演算子に対して、前後に合計2つのオペランドがあります。
このように、2つのオペランドを取る演算子を二項演算子と呼びます。
// 二項演算子とオペランドの関係
左オペランド 演算子 右オペランド
また、1つの演算子に対して1つのオペランドだけを取るものもあります。
たとえば、数値をインクリメントする++演算子は、次のように前後どちらか一方にオペランドを置きます。
let num = 1;
num++;
// または
++num;
このように、1つのオペランドを取る演算子を単項演算子と呼びます。
単項演算子と二項演算子で同じ記号を使うことがあるため、呼び方を変えています。
演算子の中でも比較演算子は、JavaScriptでも特に挙動が理解しにくい暗黙的な型変換という問題と密接な関係があります。
そのため、演算子をひととおり見た後に、暗黙的な型変換と明示的な型変換について学んでいきます。
演算子の種類は多いため、すべての演算子の動作をここで覚える必要はありません。
必要となったタイミングで、改めてその演算子の動作を見るのがよいでしょう。
1-1. 二項演算子
四則演算など基本的な二項演算子を見ていきます。
1-10. 単項マイナス演算子(-)
単項マイナス演算子はマイナスの数値を記述する場合に利用します。
たとえば、マイナスの1という数値を -1 と書くことができるのは、単項マイナス演算子を利用しているからです。
また、単項マイナス演算子はマイナスの数値を反転できます。
そのため、"マイナスのマイナスの数値"はプラスの数値となります。
単項マイナス演算子も文字列などを数値へ変換します。
また、数値へ変換できない文字列などをオペランドに指定した場合は、NaNという特殊な値になります。
そのため、単項プラス演算子と同じく、文字列から数値への変換に単項マイナス演算子を使うべきではありません。
たとえば、マイナスの1という数値を -1 と書くことができるのは、単項マイナス演算子を利用しているからです。
console.log(-1); // => -1
また、単項マイナス演算子はマイナスの数値を反転できます。
そのため、"マイナスのマイナスの数値"はプラスの数値となります。
console.log(-(-1)); // => 1
単項マイナス演算子も文字列などを数値へ変換します。
console.log(-"1"); // => -1
また、数値へ変換できない文字列などをオペランドに指定した場合は、NaNという特殊な値になります。
そのため、単項プラス演算子と同じく、文字列から数値への変換に単項マイナス演算子を使うべきではありません。
console.log(-"文字列"); // => NaN
1-11. インクリメント演算子(++)
インクリメント演算子(++)は、オペランドの数値を+1する演算子です。
オペランドの前後どちらかにインクリメント演算子を置くことで、オペランドに対して値を+1した値を返します。
インクリメント演算子(++)は、オペランドの前後どちらに置くかによって評価の順番が異なります。
後置インクリメント演算子(num++)は、次のような順で処理が行われます。
numの評価結果を返す
numに対して+1する
そのため、num++が返す値は+1する前の値となります。
一方、前置インクリメント演算子(++num)は、次のような順で処理が行われます。
numに対して+1する
numの評価結果を返す
そのため、++numが返す値は+1した後の値となります。
この2つの使い分けが必要となる場面は多くありません。
そのため、評価の順番が異なることだけを覚えておけば問題ないと言えます。
オペランドの前後どちらかにインクリメント演算子を置くことで、オペランドに対して値を+1した値を返します。
let num = 1;
num++;
console.log(num); // => 2
// 次のようにした場合と結果は同じ
// num = num + 1;
インクリメント演算子(++)は、オペランドの前後どちらに置くかによって評価の順番が異なります。
後置インクリメント演算子(num++)は、次のような順で処理が行われます。
numの評価結果を返す
numに対して+1する
そのため、num++が返す値は+1する前の値となります。
let x = 1;
console.log(x++); // => 1
console.log(x); // => 2
一方、前置インクリメント演算子(++num)は、次のような順で処理が行われます。
numに対して+1する
numの評価結果を返す
そのため、++numが返す値は+1した後の値となります。
let x = 1;
console.log(++x); // => 2
console.log(x); // => 2
この2つの使い分けが必要となる場面は多くありません。
そのため、評価の順番が異なることだけを覚えておけば問題ないと言えます。
1-12. デクリメント演算子(--)
デクリメント演算子(--)は、オペランドの数値を-1する演算子です。
デクリメント演算子は、インクリメント演算子と同様に、オペランドの前後のどちらかに置くことができます。
デクリメント演算子も、前後どちらに置くかで評価の順番が変わります。
let num = 1;
num--;
console.log(num); // => 0
// 次のようにした場合と結果は同じ
// num = num - 1;
デクリメント演算子は、インクリメント演算子と同様に、オペランドの前後のどちらかに置くことができます。
デクリメント演算子も、前後どちらに置くかで評価の順番が変わります。
// 後置デクリメント演算子
let x = 1;
console.log(x--); // => 1
console.log(x); // => 0
// 前置デクリメント演算子
let y = 1;
console.log(--y); // => 0
console.log(y); // => 0
1-13. 比較演算子
比較演算子はオペランド同士の値を比較し、真偽値を返す演算子です。
1-14. 厳密等価演算子(===)
厳密等価演算子は、左右の2つのオペランドを比較します。
同じ型で同じ値である場合に、trueを返します。
また、オペランドがどちらもオブジェクトであるときは、 オブジェクトの参照が同じである場合に、trueを返します。
次のコードでは、空のオブジェクトリテラル({})同士を比較しています。
オブジェクトリテラルは、新しいオブジェクトを作成します。
そのため、異なるオブジェクトを参照する変数を===で比較するとfalseを返します。
同じ型で同じ値である場合に、trueを返します。
console.log(1 === 1); // => true
console.log(1 === "1"); // => false
実行
また、オペランドがどちらもオブジェクトであるときは、 オブジェクトの参照が同じである場合に、trueを返します。
次のコードでは、空のオブジェクトリテラル({})同士を比較しています。
オブジェクトリテラルは、新しいオブジェクトを作成します。
そのため、異なるオブジェクトを参照する変数を===で比較するとfalseを返します。
// {} は新しいオブジェクトを作成している
const objA = {};
const objB = {};
// 生成されたオブジェクトは異なる参照となる
console.log(objA === objB); // => false
// 同じ参照を比較している場合
console.log(objA === objA); // => true
1-15. 厳密不等価演算子(!==)
厳密不等価演算子は、左右の2つのオペランドを比較します。
異なる型または異なる値である場合に、trueを返します。
===を反転した結果を返す演算子となります。
異なる型または異なる値である場合に、trueを返します。
console.log(1 !== 1); // => false
console.log(1 !== "1"); // => true
===を反転した結果を返す演算子となります。
1-16. 等価演算子(==)
等価演算子(==)は、2つのオペランドを比較します。
同じデータ型のオペランドを比較する場合は、厳密等価演算子(===)と同じ結果になります。
しかし、等価演算子(==)はオペランド同士が異なる型の値であった場合に、 同じ型となるように暗黙的な型変換をしてから比較します。
そのため、次のような、見た目からは結果を予測できない挙動が多く存在します。
意図しない挙動となることがあるため、暗黙的な型変換が行われる等価演算子(==)を使うべきではありません。
代わりに、厳密等価演算子(===)を使い、異なる型を比較したい場合は明示的に型を合わせるべきです。
例外的に、等価演算子(==)が使われるケースとして、nullとundefinedの比較があります。
次のように、比較したいオペランドが null または undefined であることを判定したい場合に、 厳密等価演算子(===)では二度比較する必要があります。
等価演算子(==)ではnullとundefinedの比較結果はtrueとなるため、一度の比較でよくなります。
このように等価演算子(==)を使う例外的なケースはありますが、 等価演算子(==)は暗黙的な型変換をするため、バグを引き起こしやすいです。
そのため、仕組みを理解するまでは常に厳密等価演算子(===)を利用することを推奨します。
同じデータ型のオペランドを比較する場合は、厳密等価演算子(===)と同じ結果になります。
console.log(1 == 1); // => true
console.log("str" == "str"); // => true
console.log("JavaScript" == "ECMAScript"); // => false
// オブジェクトは参照が一致しているならtrueを返す
// {} は新しいオブジェクトを作成している
const objA = {};
const objB = {};
console.log(objA == objB); // => false
console.log(objA == objA); // => true
しかし、等価演算子(==)はオペランド同士が異なる型の値であった場合に、 同じ型となるように暗黙的な型変換をしてから比較します。
そのため、次のような、見た目からは結果を予測できない挙動が多く存在します。
// 文字列を数値に変換してから比較
console.log(1 == "1"); // => true
// "01"を数値にすると`1`となる
console.log(1 == "01"); // => true
// 真偽値を数値に変換してから比較
console.log(0 == false); // => true
// nullの比較はfalseを返す
console.log(0 == null); // => false
// nullとundefinedの比較は常にtrueを返す
console.log(null == undefined); // => true
意図しない挙動となることがあるため、暗黙的な型変換が行われる等価演算子(==)を使うべきではありません。
代わりに、厳密等価演算子(===)を使い、異なる型を比較したい場合は明示的に型を合わせるべきです。
例外的に、等価演算子(==)が使われるケースとして、nullとundefinedの比較があります。
次のように、比較したいオペランドが null または undefined であることを判定したい場合に、 厳密等価演算子(===)では二度比較する必要があります。
等価演算子(==)ではnullとundefinedの比較結果はtrueとなるため、一度の比較でよくなります。
const value = undefined; /* または null */
// === では2つの値と比較しないといけない
if (value === null || value === undefined) {
console.log("valueがnullまたはundefinedである場合の処理");
}
// == では null と比較するだけでよい
if (value == null) {
console.log("valueがnullまたはundefinedである場合の処理");
}
このように等価演算子(==)を使う例外的なケースはありますが、 等価演算子(==)は暗黙的な型変換をするため、バグを引き起こしやすいです。
そのため、仕組みを理解するまでは常に厳密等価演算子(===)を利用することを推奨します。
1-17. 不等価演算子(!=)
不等価演算子(!=)は、2つのオペランドを比較し、等しくないならtrueを返します。
不等価演算子も、等価演算子(==)と同様に異なる型のオペランドを比較する際に、暗黙的な型変換をしてから比較します。
そのため、不等価演算子(!=)は、利用するべきではありません。
代わりに暗黙的な型変換をしない厳密不等価演算子(!==)を利用します。
大なり演算子/より大きい(>)
大なり演算子は、左オペランドが右オペランドより大きいならば、trueを返します。
大なりイコール演算子/以上(>=)
大なりイコール演算子は、左オペランドが右オペランドより大きいまたは等しいならば、trueを返します。
小なり演算子/より小さい(<)
小なり演算子は、左オペランドが右オペランドより小さいならば、trueを返します。
小なりイコール演算子/以下(<=)
小なりイコール演算子は、左オペランドが右オペランドより小さいまたは等しいならば、trueを返します。
console.log(1 != 1); // => false
console.log("str" != "str"); // => false
console.log("JavaScript" != "ECMAScript"); // => true
console.log(true != true);// => false
// オブジェクトは参照が一致していないならtrueを返す
const objA = {};
const objB = {};
console.log(objA != objB); // => true
console.log(objA != objA); // => false
不等価演算子も、等価演算子(==)と同様に異なる型のオペランドを比較する際に、暗黙的な型変換をしてから比較します。
console.log(1 != "1"); // => false
console.log(0 != false); // => false
console.log(0 != null); // => true
console.log(null != undefined); // => false
そのため、不等価演算子(!=)は、利用するべきではありません。
代わりに暗黙的な型変換をしない厳密不等価演算子(!==)を利用します。
大なり演算子/より大きい(>)
大なり演算子は、左オペランドが右オペランドより大きいならば、trueを返します。
console.log(42 > 21); // => true
console.log(42 > 42); // => false
大なりイコール演算子/以上(>=)
大なりイコール演算子は、左オペランドが右オペランドより大きいまたは等しいならば、trueを返します。
console.log(42 >= 21); // => true
console.log(42 >= 42); // => true
console.log(42 >= 43); // => false
実行
小なり演算子/より小さい(<)
小なり演算子は、左オペランドが右オペランドより小さいならば、trueを返します。
console.log(21 < 42); // => true
console.log(42 < 42); // => false
小なりイコール演算子/以下(<=)
小なりイコール演算子は、左オペランドが右オペランドより小さいまたは等しいならば、trueを返します。
console.log(21 <= 42); // => true
console.log(42 <= 42); // => true
console.log(43 <= 42); // => false
1-2. プラス演算子(+)
2つの数値を加算する演算子です。
console.log(1 + 1); // => 2
1-3. マイナス演算子(-)
2つの数値を減算する演算子です。左オペランドから右オペランドを減算した値を返します。
console.log(1 - 1); // => 0
console.log(10 - 0.5); // => 9.5
1-4. 乗算演算子(*)
2つの数値を乗算する演算子です。
console.log(2 * 8); // => 16
console.log(10 * 0.5); // => 5
1-5. 除算演算子(/)
2つの数値を除算する演算子です。左オペランドを右オペランドで除算した値を返します。
ただし、任意の数値を0で除算した結果は、無限大を表す数値であるInfinityとなります。
console.log(8 / 2); // => 4
console.log(10 / 0.5); // => 20
ただし、任意の数値を0で除算した結果は、無限大を表す数値であるInfinityとなります。
console.log(10 / 0); // => Infinity
1-6. 剰余演算子(%)
2つの数値を除算したあまりを求める演算子です。
左オペランドを右オペランドで除算したあまりを返します。
左オペランドを右オペランドで除算したあまりを返します。
console.log(8 % 2); // => 0
console.log(9 % 2); // => 1
console.log(10 % 0.5); // => 0
console.log(10 % 4.5); // => 1
1-7. [ES2016] べき乗演算子(**)
2つの数値のべき乗を求める演算子です。
左オペランドを右オペランドでべき乗した値を返します。
べき乗演算子と同じ動作をするMath.powメソッドがあります。
べき乗演算子はES2016で後から追加された演算子であるため、関数と演算子がそれぞれ存在しています。
一方、他の二項演算子は演算子が先に存在していたため、Mathには対応するメソッドがありません。
左オペランドを右オペランドでべき乗した値を返します。
// べき乗演算子(ES2016)で2の4乗を計算
console.log(2 ** 4); // => 16
べき乗演算子と同じ動作をするMath.powメソッドがあります。
console.log(Math.pow(2, 4)); // => 16
べき乗演算子はES2016で後から追加された演算子であるため、関数と演算子がそれぞれ存在しています。
一方、他の二項演算子は演算子が先に存在していたため、Mathには対応するメソッドがありません。
1-8. 単項演算子(算術)
単項演算子は、1つのオペランドを受け取り処理する演算子です。
1-9. 単項プラス演算子(+)
単項演算子の+はオペランドを数値に変換します。
次のコードでは、数値の1を数値へ変換するため、結果は変わらず数値の1です。
+数値のように数値に対して、単項プラス演算子をつけるケースはほぼ無いでしょう。
また、単項プラス演算子は、数値以外も数値へと変換します。
次のコードでは、数字(文字列)を数値へ変換しています。
一方、数値に変換できない文字列などはNaNという特殊な値へと変換されます。
NaNは"Not-a-Number"の略称で、数値ではないがNumber型の値を表現しています。
NaNはどの値とも(NaN自身に対しても)一致しない特性があり、Number.isNaNメソッドを使うことでNaNの判定を行えます。
しかし、単項プラス演算子は文字列から数値への変換に使うべきではありません。
なぜなら、Numberコンストラクタ関数やparseInt関数などの明示的な変換方法が存在するためです。
次のコードでは、数値の1を数値へ変換するため、結果は変わらず数値の1です。
+数値のように数値に対して、単項プラス演算子をつけるケースはほぼ無いでしょう。
console.log(+1); // => 1
また、単項プラス演算子は、数値以外も数値へと変換します。
次のコードでは、数字(文字列)を数値へ変換しています。
console.log(+"1"); // => 1
一方、数値に変換できない文字列などはNaNという特殊な値へと変換されます。
// 数値でない文字列はNaNという値に変換される
console.log(+"文字列"); // => NaN
NaNは"Not-a-Number"の略称で、数値ではないがNumber型の値を表現しています。
NaNはどの値とも(NaN自身に対しても)一致しない特性があり、Number.isNaNメソッドを使うことでNaNの判定を行えます。
// 自分自身とも一致しない
console.log(NaN === NaN); // => false
// Number型である
console.log(typeof NaN); // => "number"
// Number.isNaNでNaNかどうかを判定
console.log(Number.isNaN(NaN)); // => tru
しかし、単項プラス演算子は文字列から数値への変換に使うべきではありません。
なぜなら、Numberコンストラクタ関数やparseInt関数などの明示的な変換方法が存在するためです。