JavaScript:演算子と比較(=== の重要性)
1学習の目的
- 四則演算と複合代入、そして比較演算子を正確に使えるようになる。とくに == と === の違いを理解し、意図しない一致を防げるようになる。
- 論理演算子と短絡評価を使って、条件の組み立てや既定値の指定を簡潔に書けるようになる。次章の条件分岐の土台がここで完成する。
2基礎解説
| 種類 | 記号 | 例と結果 |
|---|---|---|
| 算術 | + - * / % ** | 7 % 2 → 1(余り) |
| 複合代入 | += -= *= /= | total += 10 |
| 厳密比較 | === !== | 1 === "1" → false |
| 論理 | && || ! | かつ/または/否定 |
- 比較は必ず === を使う。== は型を自動変換して比較するため 1 == "1" が true になる。この曖昧さがバグの温床で、実務では === が絶対的な標準。
- 割り算は整数同士でも小数になる(7 / 2 は 3.5)。整数が欲しければ Math.floor()。余りは %。
- && は両方trueで true、|| はどちらかtrueで true。! は真偽を反転する。
- || は「左が偽なら右を返す」性質があり、既定値の指定に使える(name || "名無し")。ただし 0 や "" も偽扱いになる点に注意。
- 0・""・null・undefined・NaN は偽(falsy)として扱われる。それ以外はすべて真。if (name) だけで「空でなければ」を表現できる。
現場使用例:フォーム入力の一致確認 password === confirm、在庫と営業時間の同時判定 stock > 0 && isOpen、未設定時の既定値 config.limit || 100、偶数判定 n % 2 === 0。
console.log(7 / 2); // 3.5 ← 小数になる console.log(7 % 2); // 1 ← 余り console.log(2 ** 10); // 1024 ← べき乗 let total = 100; total += 50; // total = total + 50 console.log(total); // 150 // == と === の違い(最重要) console.log(1 == "1"); // true ← 型を変換して比較 console.log(1 === "1"); // false ← 型も含めて比較 // 論理演算子 const stock = 3; const isOpen = true; console.log(stock > 0 && isOpen); // true // || で既定値を指定できる const name = ""; console.log(name || "名無し"); // 名無し
3基本ドリル(10問)
出力 == 2
余りを求める記号は % (パーセント)。
console.log(17 % 5);
% は余りを返す演算子で、割合のパーセントとは無関係。偶数判定やグループ分けで頻繁に使う。
A. true B. false C. エラー D. undefined 選択★☆☆無料
解答 == A
== は型を自動変換してから比べる。
A
文字列の "1" が数値に変換されてから比較されるので true になる。これが意図しない一致を生む原因で、だから === を使う。
出力 == false
=== はイコール3つ。型が違えば必ず false。
console.log(1 === "1");
型が違う時点で false。値が同じでも型が違えば別物と判定してくれるので、予期せぬ挙動を防げる。
let total = 100; total ____ 50; console.log(total);
出力 == 150
「足して代入する」複合代入演算子。
+=
total += 50 は total = total + 50 の省略形。-= *= /= も同じ形で使える。
A. true B. false C. エラー D. undefined 選択★☆☆無料
解答 == B
&& は「かつ」。両方が true のときだけ true。
B
&&(かつ)は全部 trueで true、||(または)は1つでも trueなら true。
出力 == true
&& で2つの条件をつなぐ。isOpen は既にbooleanなので === true は不要。
const stock = 3; const isOpen = true; console.log(stock >= 1 && isOpen);
booleanの変数はそのまま条件に置くのがJavaScriptらしい書き方。isOpen === true は冗長。
const name = ""; console.log(name ____ "名無し");
出力 == 名無し
「または」を表す記号2つ。左が偽なら右が返る性質を使う。
||
|| は左が偽なら右を返すので既定値の指定に使える。ただし 0 も偽なので、0 を有効な値として扱いたい場合は ?? を使う。
A. 0 B. ""(空文字) C. "0"(文字列のゼロ) D. null 選択★★☆無料
解答 == C
中身があるかどうかではなく、値そのものを見る。
C
"0" は文字が1つ入った文字列なので真。空でない文字列はすべて真になる。0(数値)とは別物という点が引っかけ。
出力 == true
2で割った余りが0なら偶数。比較は === を使う。
const n = 14; console.log(n % 2 === 0);
% と === の組み合わせは偶数判定の定番。3の倍数なら n % 3 === 0 と応用できる。
出力 == 合格
条件 ? 真のときの値 : 偽のときの値 の形で書く。
const score = 82; console.log(score >= 60 ? "合格" : "不合格");
三項演算子は2択で値を決めるだけのときに使う。処理が複雑になるなら次章の if 文にしたほうが読みやすい。
4実践シナリオ(5問)
「1 == "1" → true」の形式で表示すること。
① 1 == "1" ② 1 === "1" ③ 0 == "" ④ 0 === "" コーディング★★☆無料
出力4行が完全一致
テンプレートリテラルの中に比較式を書く。左辺の表示には引用符をそのまま文字として含める。
console.log(`1 == "1" → ${1 == "1"}`);
console.log(`1 === "1" → ${1 === "1"}`);
console.log(`0 == "" → ${0 == ""}`);
console.log(`0 === "" → ${0 === ""}`);
== は 0 と空文字まで同じと判定してしまう。これはフォームの未入力チェックで深刻なバグになる。=== なら型が違う時点で false なので安全。
出力2行が完全一致
一致判定は ===。文字数は .length で取れる。
const password = "abc12345";
const confirm = "abc12345";
console.log(`一致:${password === confirm}`);
console.log(`8文字以上:${password.length >= 8}`);
パスワード確認で == を使うと、型の違う値が一致と判定される危険がある。認証系は必ず ===。
「在庫あり かつ 営業中:true」「予算内:false」「購入可能:false」
※購入可能=3つの条件すべてを満たすこと コーディング★★☆無料
出力3行が完全一致
&& を複数つなげられる。予算内は price <= budget。
const stock = 5;
const isOpen = true;
const price = 3000;
const budget = 2500;
console.log(`在庫あり かつ 営業中:${stock > 0 && isOpen}`);
console.log(`予算内:${price <= budget}`);
console.log(`購入可能:${stock > 0 && isOpen && price <= budget}`);
&& は何個でもつなげられる。1つでも false があれば全体が false になる。逆に「どれか1つでも満たせばよい」なら || を使う。
「limit1 || 100 → 100」の形式。 コーディング★★★無料
出力4行が完全一致
?? は「null か undefined のときだけ」右を返す。0 はそのまま残る。
const limit1 = 0;
const limit2 = null;
console.log(`limit1 || 100 → ${limit1 || 100}`);
console.log(`limit1 ?? 100 → ${limit1 ?? 100}`);
console.log(`limit2 || 100 → ${limit2 || 100}`);
console.log(`limit2 ?? 100 → ${limit2 ?? 100}`);
「上限0件」という設定が || では100に化ける——これは実際によくある事故。0 や "" を有効な値として扱いたいなら ?? を使うのが正解。
「送料無料:false」(5000円以上で無料)
「会員割引:あり」(三項演算子で「あり」「なし」)
「クーポン:なし」(空文字なら「なし」)
「最終判定:割引のみ適用」(会員かクーポンのどちらかがあれば「割引のみ適用」、両方なければ「割引なし」) コーディング★★★無料
出力4行が完全一致
クーポンの有無は couponCode !== "" で判定できる。最終判定は || でつないで三項演算子に渡す。
const price = 4800;
const isMember = true;
const couponCode = "";
const hasCoupon = couponCode !== "";
console.log(`送料無料:${price >= 5000}`);
console.log(`会員割引:${isMember ? "あり" : "なし"}`);
console.log(`クーポン:${hasCoupon ? "あり" : "なし"}`);
console.log(`最終判定:${isMember || hasCoupon ? "割引のみ適用" : "割引なし"}`);
判定結果を hasCoupon という変数に切り出すのがポイント。条件式に名前を付けると、後半の複合条件が一気に読みやすくなる。実務では長い条件式ほど名前を付けて分解する。
5仕上げ課題
const price = 12800;
const qty = 3;
const stock = 5;
const isMember = true;
const budget = 40000;
const inputQty = "3"; // フォームから来た文字列
仕様:
① 小計(price × qty)を計算
② 会員なら10%引き(Math.round で整数化)
③ 在庫が足りているか(qty ≦ stock)
④ 予算内か(割引後 ≦ budget)
⑤ 入力された数量が正しいかを === で厳密に確認(inputQty は文字列なので Number() で変換してから比較)
⑥ すべて満たせば「注文可能」、1つでも欠ければ「注文不可」
出力仕様(7行):
=== 注文チェック ===
小計:38,400円
割引後:34,560円
在庫OK:true(3 / 5個)
予算内:true
数量の照合:true
判定:注文可能
出力7行が完全一致
判定結果はそれぞれ const に入れて名前を付けてから、最後に && でまとめる。数量の照合は Number(inputQty) === qty。金額表示は toLocaleString()。
const price = 12800;
const qty = 3;
const stock = 5;
const isMember = true;
const budget = 40000;
const inputQty = "3";
const subtotal = price * qty;
const discounted = isMember ? Math.round(subtotal * 0.9) : subtotal;
const stockOk = qty <= stock;
const budgetOk = discounted <= budget;
const qtyOk = Number(inputQty) === qty;
const canOrder = stockOk && budgetOk && qtyOk;
console.log("=== 注文チェック ===");
console.log(`小計:${subtotal.toLocaleString()}円`);
console.log(`割引後:${discounted.toLocaleString()}円`);
console.log(`在庫OK:${stockOk}(${qty} / ${stock}個)`);
console.log(`予算内:${budgetOk}`);
console.log(`数量の照合:${qtyOk}`);
console.log(`判定:${canOrder ? "注文可能" : "注文不可"}`);
判定を1つずつ変数に切り出してから && でまとめる——これがこの課題の核心。すべてを1行の巨大な条件式に詰め込むと、false になったときどの条件で落ちたのか分からなくなる。名前を付けておけば、出力を見るだけで原因が特定できる。
そして⑤が最重要だ。Number(inputQty) === qty と書けば、"3" と 3 を厳密に照合できる。ここで == を使うと変換なしでも true になってしまい、「たまたま動いている」コードになる。動くかどうかではなく、意図どおりに動くと言い切れるか——それが === を使う理由。
次章では if 文と switch を学ぶ。ここで作った真偽値が、実際に処理を分岐させる材料になる。