比較演算子と ===
このレッスンで分かること
===は型と値の両方を見て比べます==は比べる前に型をこっそり変換するので、結果が直感とズレます
見た目が同じなのに一致しない
プロフィールサイトの入力欄に西暦を打ち込んでもらい、それが今年かどうかを判定したいとします。ところが、入力欄から取り出した値は数字を打っても必ず文字列で届きます。
JavaScript
const year = "2026"; // 入力欄から届いた値
console.log(year === 2026); // false 型が違う
console.log(year === "2026"); // true=== は厳密等価と呼び、型と値の両方が同じときだけ true を返します。人間の目には同じ「2026」でも、JavaScript にとって数値と文字列は別物です。仲間には !==(厳密非等価)と > < >= <=(大小)があり、どれも返るのは true か false の boolean です。値そのものを書き換えることはありません。
== は比べる前に型をそろえてしまう
JavaScript にはもうひとつ == という等価演算子があります。左右の型が違うとき、比較の前に型を変換してから比べます。この変換ルールが独特です。
| 式 | == の結果 | 何が起きているか |
|---|---|---|
0 == "" | true | 空文字が数値の 0 に変換される |
0 == "0" | true | 文字列 "0" が数値の 0 に変換される |
"" == "0" | false | 文字列同士なので変換せず比べる |
0 == false | true | false が数値の 0 に変換される |
null == undefined | true | この 2 つだけ特別扱いで等しい |
上から 3 行を並べてください。0 と "" が等しく、0 と "0" も等しいのに、"" と "0" は等しくありません。「A と B が等しく、B と C が等しいなら A と C も等しい」が成り立っていません。ルール表を暗記していない人には結果が予測できない、ということです。
JavaScript
console.log(0 == ""); // true
console.log(0 == "0"); // true
console.log("" == "0"); // false
console.log(0 === ""); // false
console.log(0 === "0"); // false=== なら「型が違えばその時点で false」という規則ひとつで済みます。読む人が頭の中でルール表を引かずに済むぶん、安全です。
型変換とは別に、比較そのものが通用しない値がひとつだけあります。数値に変換できなかったときに現れる NaN です。NaN === NaN すら false になるので、NaN かどうかは Number.isNaN で調べます。
JavaScript
const views = Number("たくさん"); // NaN
console.log(views === NaN); // false いつでも false
console.log(Number.isNaN(views)); // true現場では ESLint の
eqeqeqルールで==を機械的に禁止していることがほとんどです。数値と文字列を比べたいときは==に任せず、Number(year) === 2026のように自分で型をそろえてから===で比べます。
よくある間違い
=と==と===を取り違える —=は代入です。比較のつもりでisPinned = trueと書くと、値を書き換えたうえで常に成立する条件ができあがります。等しいかを調べたいときは記号を 3 つ書く、と体に覚えさせてください
JavaScript
let isPinned = false;
console.log(isPinned = true); // true 代入した値がそのまま返る
console.log(isPinned === true); // true こちらが比較- 境界の値を落とす — 「100 以上」を
> 100と書くと 100 ちょうどが漏れます。>=と<=は等号を含む、と毎回声に出して確かめてください
要件
- 関数名は
checkEquality、引数はaとbの 2 つにすること - 戻り値は
looseとstrictの 2 つのキーを持つオブジェクトにすること looseにはa == b、strictにはa === bの結果 (どちらも boolean) を入れること
入出力例
checkEquality(2026, "2026") → {"loose":true,"strict":false}
checkEquality(0, "") → {"loose":true,"strict":false}
checkEquality(null) → {"loose":true,"strict":false}
checkEquality("プロフィールサイト", "プロフィールサイト") → {"loose":true,"strict":true}
checkEquality(false, 0) → {"loose":true,"strict":false}