はじめに

JavaScriptでプログラムを書く上で、演算子(オペレーター)の理解は欠かせません。演算子とは、値に対して計算や比較、論理判定などの操作を行うための記号のことです。

本記事では、JavaScriptの演算子を以下の3つのカテゴリに分けて、初心者向けにわかりやすく解説します。

  • 算術演算子: 数値の計算を行う(+-*/など)
  • 比較演算子: 値を比較して真偽値を返す(=====<>など)
  • 論理演算子: 複数の条件を組み合わせる(&&||!など)

また、ES2020以降に追加されたモダンな演算子である「Null合体演算子(??)」や「オプショナルチェーン演算子(?.)」についても紹介します。

算術演算子

算術演算子は、数値に対して四則演算などの計算を行うための演算子です。他のプログラミング言語と同様の使い方ができます。

基本的な算術演算子

演算子 名称 説明
+ 加算 2つの値を足す 5 + 38
- 減算 左辺から右辺を引く 5 - 32
* 乗算 2つの値を掛ける 5 * 315
/ 除算 左辺を右辺で割る 6 / 32
% 剰余 除算の余りを求める 7 % 31
** べき乗 左辺を右辺乗する 2 ** 38

基本的な算術演算子の使用例を見てみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 加算
console.log(10 + 5); // 15

// 減算
console.log(10 - 5); // 5

// 乗算
console.log(10 * 5); // 50

// 除算
console.log(10 / 4); // 2.5(整数同士でも小数点以下が返る)

// 剰余(余り)
console.log(10 % 3); // 1(10÷3の余り)

// べき乗(ES2016で追加)
console.log(2 ** 10); // 1024(2の10乗)

除算における注意点

JavaScriptでは、0で除算してもエラーにはならずInfinity(無限大)が返されます。

1
2
3
console.log(10 / 0);  // Infinity
console.log(-10 / 0); // -Infinity
console.log(0 / 0);   // NaN(Not a Number: 数値ではない)

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

変数の値を1増減させる演算子として、インクリメント演算子(++)とデクリメント演算子(--)があります。

1
2
3
4
5
6
7
8
9
let count = 5;

// インクリメント(1を加える)
count++;
console.log(count); // 6

// デクリメント(1を引く)
count--;
console.log(count); // 5

前置と後置で挙動が異なる点に注意が必要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let a = 5;
let b = 5;

// 後置インクリメント: 現在の値を返してから加算
console.log(a++); // 5(先に5を返す)
console.log(a);   // 6(その後1が加算されている)

// 前置インクリメント: 先に加算してから値を返す
console.log(++b); // 6(先に加算してから返す)
console.log(b);   // 6

文字列の結合

+演算子は数値の加算だけでなく、文字列の結合にも使用されます。

1
2
3
4
5
const firstName = "太郎";
const lastName = "山田";
const fullName = lastName + firstName;

console.log(fullName); // "山田太郎"

数値と文字列を+で結合すると、数値が文字列に変換されます。

1
2
3
console.log("価格: " + 1000 + "円"); // "価格: 1000円"
console.log(10 + 20 + "円");         // "30円"(左から評価されるため)
console.log("合計" + 10 + 20);       // "合計1020"(最初が文字列なので結合される)

複合代入演算子

算術演算子と代入を組み合わせた省略記法もあります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let num = 10;

num += 5;  // num = num + 5 と同じ → 15
num -= 3;  // num = num - 3 と同じ → 12
num *= 2;  // num = num * 2 と同じ → 24
num /= 4;  // num = num / 4 と同じ → 6
num %= 4;  // num = num % 4 と同じ → 2
num **= 3; // num = num ** 3 と同じ → 8

console.log(num); // 8

比較演算子

比較演算子は、2つの値を比較し、その結果を真偽値(trueまたはfalse)で返す演算子です。条件分岐やループ処理で頻繁に使用されます。

比較演算子の一覧

演算子 名称 説明
== 等価 値が等しければtrue 5 == "5"true
!= 不等価 値が等しくなければtrue 5 != "3"true
=== 厳密等価 値と型が等しければtrue 5 === "5"false
!== 厳密不等価 値または型が異なればtrue 5 !== "5"true
> 大なり 左辺が右辺より大きければtrue 5 > 3true
>= 以上 左辺が右辺以上であればtrue 5 >= 5true
< 小なり 左辺が右辺より小さければtrue 3 < 5true
<= 以下 左辺が右辺以下であればtrue 5 <= 5true

等価演算子(==)と厳密等価演算子(===)の違い

JavaScriptには2種類の等価演算子があり、その違いを正しく理解することが重要です。

等価演算子(== は、比較する前に型変換(型の強制変換)を行います。

1
2
3
4
console.log(5 == "5");     // true(文字列"5"が数値5に変換される)
console.log(0 == false);   // true(falseが0に変換される)
console.log(null == undefined); // true(特別なルール)
console.log("" == false);  // true(空文字列は0、falseも0に変換される)

厳密等価演算子(=== は、型変換を行わず、値と型の両方が一致する場合のみtrueを返します。

1
2
3
4
console.log(5 === "5");    // false(型が異なる: number vs string)
console.log(0 === false);  // false(型が異なる: number vs boolean)
console.log(null === undefined); // false(型が異なる)
console.log(5 === 5);      // true(値も型も同じ)

予期しないバグを防ぐため、原則として厳密等価演算子(===)を使用することを推奨します

flowchart TD
    A[比較演算子を使用] --> B{型変換が必要?}
    B -->|はい| C[== を検討]
    B -->|いいえ| D[=== を使用]
    C --> E[意図的な型変換か確認]
    E -->|はい| F[== を使用]
    E -->|いいえ| D
    D --> G[推奨: 常に === を使う]

大小比較

数値や文字列の大小を比較する演算子も用意されています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 数値の比較
console.log(10 > 5);  // true
console.log(10 >= 10); // true
console.log(5 < 10);  // true
console.log(5 <= 5);  // true

// 文字列の比較(辞書順で比較される)
console.log("apple" < "banana"); // true
console.log("abc" < "abd");      // true
console.log("A" < "a");          // true(大文字は小文字より小さい)

NaNとの比較

NaN(Not a Number)は特殊な値で、自分自身とも等しくなりません。

1
2
3
4
5
6
console.log(NaN === NaN); // false
console.log(NaN == NaN);  // false

// NaNかどうかを判定するにはNumber.isNaN()を使用する
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN("hello")); // false

論理演算子

論理演算子は、複数の条件を組み合わせたり、真偽値を反転させたりするための演算子です。条件分岐で複雑な条件を表現する際に不可欠です。

論理演算子の一覧

演算子 名称 説明
&& 論理積(AND) 両方がtrueならtrue true && falsefalse
|| 論理和(OR) どちらかがtrueならtrue true || falsetrue
! 論理否定(NOT) 真偽値を反転する !truefalse

論理積演算子(&&)

&&演算子は、すべての条件がtrueの場合にtrueを返します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const age = 25;
const hasLicense = true;

// 両方の条件が満たされているか確認
if (age >= 18 && hasLicense) {
  console.log("運転できます");
}

// 真偽値の組み合わせ
console.log(true && true);   // true
console.log(true && false);  // false
console.log(false && true);  // false
console.log(false && false); // false

論理和演算子(||)

||演算子は、いずれかの条件がtrueの場合にtrueを返します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const isWeekend = true;
const isHoliday = false;

// どちらかの条件が満たされているか確認
if (isWeekend || isHoliday) {
  console.log("お休みです");
}

// 真偽値の組み合わせ
console.log(true || true);   // true
console.log(true || false);  // true
console.log(false || true);  // true
console.log(false || false); // false

論理否定演算子(!)

!演算子は、真偽値を反転させます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const isLoggedIn = false;

if (!isLoggedIn) {
  console.log("ログインしてください");
}

console.log(!true);  // false
console.log(!false); // true

// 二重否定で真偽値に変換
console.log(!!"hello"); // true(truthy値をtrueに変換)
console.log(!!"");      // false(空文字列はfalsy値)
console.log(!!0);       // false
console.log(!!1);       // true

短絡評価(ショートサーキット)

論理演算子は「短絡評価」という仕組みを持っています。これは、結果が確定した時点で残りの評価を行わないという特性です。

1
2
3
4
5
// && の短絡評価: 左辺がfalsyなら右辺は評価されない
console.log(false && console.log("実行されない")); // false

// || の短絡評価: 左辺がtruthyなら右辺は評価されない
console.log(true || console.log("実行されない")); // true

この特性を利用して、値の代入やデフォルト値の設定によく使われます。

1
2
3
4
5
6
// ||を使ったデフォルト値の設定(従来の方法)
const username = inputName || "ゲスト";

// &&を使った条件付き実行
const isAdmin = true;
isAdmin && console.log("管理者メニューを表示");

truthyとfalsy

JavaScriptでは、すべての値を真偽値として評価できます。

falsy値(falseとして扱われる値):

  • false
  • 0-0
  • ""(空文字列)
  • null
  • undefined
  • NaN

truthy値(上記以外のすべての値):

  • true
  • 0以外の数値
  • 空でない文字列
  • オブジェクト(空のオブジェクトや配列も含む)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// falsyな値の例
if (0) {
  console.log("実行されない");
}

if ("") {
  console.log("実行されない");
}

// truthyな値の例
if ("hello") {
  console.log("実行される");
}

if ([]) {
  console.log("空配列もtruthy"); // 実行される
}

if ({}) {
  console.log("空オブジェクトもtruthy"); // 実行される
}

Null合体演算子(??)

ES2020で導入されたNull合体演算子(??)は、左辺がnullまたはundefinedの場合にのみ右辺の値を返します。

基本的な使い方

1
2
3
4
const username = null;
const displayName = username ?? "ゲスト";

console.log(displayName); // "ゲスト"

||演算子との違い

||演算子はfalsyな値すべてで右辺を返しますが、??演算子はnullundefinedの場合のみ右辺を返します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// ||演算子の場合
console.log(0 || 100);       // 100(0はfalsyなので右辺が返る)
console.log("" || "default"); // "default"(空文字列はfalsyなので右辺が返る)
console.log(false || true);   // true

// ??演算子の場合
console.log(0 ?? 100);       // 0(0はnull/undefinedではないので左辺が返る)
console.log("" ?? "default"); // ""(空文字列はnull/undefinedではないので左辺が返る)
console.log(false ?? true);   // false

// nullとundefinedの場合は同じ挙動
console.log(null ?? "default");      // "default"
console.log(undefined ?? "default"); // "default"

この違いは、0や空文字列を有効な値として扱いたい場合に重要です。

1
2
3
4
5
6
7
8
// ユーザーの入力値が0の場合
const userInput = 0;

// ||を使うと0は無視されてしまう
const valueA = userInput || 10; // 10

// ??を使うと0も有効な値として扱われる
const valueB = userInput ?? 10; // 0

Null合体代入演算子(??=)

ES2021では、Null合体代入演算子(??=)も追加されました。

1
2
3
4
5
6
7
8
9
let value = null;
value ??= "default"; // valueがnull/undefinedの場合のみ代入

console.log(value); // "default"

let count = 0;
count ??= 100; // countは0なので代入されない

console.log(count); // 0

オプショナルチェーン演算子(?.)

ES2020で導入されたオプショナルチェーン演算子(?.)は、オブジェクトのプロパティに安全にアクセスするための演算子です。

基本的な使い方

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const user = {
  name: "太郎",
  address: {
    city: "東京"
  }
};

// 従来の書き方(エラーを防ぐための冗長なチェック)
const city = user && user.address && user.address.city;

// オプショナルチェーンを使用
const cityName = user?.address?.city;

console.log(cityName); // "東京"

nullやundefinedの場合

プロパティが存在しない場合や、途中の値がnullまたはundefinedの場合、エラーを発生させずにundefinedを返します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const user = {
  name: "太郎"
  // addressプロパティは存在しない
};

// 従来の方法: エラーが発生する
// console.log(user.address.city); // TypeError: Cannot read properties of undefined

// オプショナルチェーン: undefinedが返る
console.log(user?.address?.city); // undefined

// nullの場合も同様
const user2 = {
  name: "花子",
  address: null
};

console.log(user2?.address?.city); // undefined

関数呼び出しでの使用

メソッドが存在するかわからない場合にも使用できます。

1
2
3
4
5
6
7
const api = {
  getData: () => "データ"
};

// メソッドが存在すれば呼び出す
console.log(api.getData?.()); // "データ"
console.log(api.getUser?.()); // undefined(メソッドが存在しないためundefined)

配列へのアクセス

配列の要素にアクセスする際にも使用できます。

1
2
3
4
5
6
7
const users = [
  { name: "太郎", age: 25 },
  { name: "花子", age: 30 }
];

console.log(users?.[0]?.name); // "太郎"
console.log(users?.[10]?.name); // undefined(インデックス10は存在しない)

Null合体演算子との組み合わせ

?.??を組み合わせることで、プロパティが存在しない場合のデフォルト値を設定できます。

1
2
3
4
5
6
7
const user = {
  name: "太郎"
};

const city = user?.address?.city ?? "住所未登録";

console.log(city); // "住所未登録"

三項演算子

三項演算子(条件演算子)は、条件に基づいて2つの値のいずれかを返す、JavaScriptで唯一の3つのオペランドを取る演算子です。

基本的な構文

1
2
// 構文: 条件 ? 真の場合の値 : 偽の場合の値
const result = condition ? valueIfTrue : valueIfFalse;

使用例

1
2
3
4
5
6
7
const age = 20;
const status = age >= 18 ? "成人" : "未成年";

console.log(status); // "成人"

// 変数への代入以外にも使用可能
console.log(age >= 20 ? "お酒を購入できます" : "お酒は購入できません");

ネストは避ける

三項演算子はネストできますが、可読性が著しく低下するため避けるべきです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 悪い例: ネストした三項演算子
const grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "D";

// 良い例: if文を使用
let grade;
if (score >= 90) {
  grade = "A";
} else if (score >= 80) {
  grade = "B";
} else if (score >= 70) {
  grade = "C";
} else {
  grade = "D";
}

演算子の優先順位

複数の演算子を組み合わせる場合、演算子の優先順位を理解しておくことが重要です。

主要な演算子の優先順位(高い順)

優先度 演算子 説明
() グループ化
?. オプショナルチェーン
++-- インクリメント/デクリメント
! 論理否定
** べき乗
*/% 乗算、除算、剰余
+- 加算、減算
<<=>>= 比較
==!====!== 等価
&& 論理積
|| 論理和
?? Null合体
? : 三項演算子
=+=など 代入
1
2
3
4
5
6
7
8
9
// 優先順位の例
const result = 2 + 3 * 4; // 14(乗算が先に評価される)
const result2 = (2 + 3) * 4; // 20(括弧で優先順位を変更)

// 論理演算子の優先順位
const a = true || false && false;
// &&が先に評価されるため: true || (false && false) → true || false → true

console.log(a); // true

まとめ

本記事では、JavaScriptの演算子について以下の内容を解説しました。

  • 算術演算子: 加算、減算、乗算、除算、剰余、べき乗の基本的な使い方
  • 比較演算子: 等価(==)と厳密等価(===)の違い、大小比較
  • 論理演算子: AND、OR、NOTと短絡評価の仕組み
  • モダンな演算子: Null合体演算子(??)とオプショナルチェーン演算子(?.

演算子を正しく理解し使い分けることで、より安全で読みやすいコードを書くことができます。特に以下の点を意識してください。

  • 比較には原則として厳密等価演算子(===)を使用する
  • デフォルト値の設定には||より??を検討する
  • ネストしたオブジェクトへのアクセスには?.を活用する
  • 三項演算子のネストは避け、複雑な条件はif文を使用する

参考リンク