比較演算子と ===
このレッスンで分かること
===は型と値の両方を見て比べます==は比べる前に型をこっそり変換するので、結果が直感とズレます
見た目が同じなのに一致しない
プロフィールサイトの入力欄に西暦を打ち込んでもらい、それが今年かどうかを判定したいとします。ところが、入力欄から取り出した値は数字を打っても必ず文字列で届きます。
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のように自分で型をそろえてから===で比べます。
比較した結果を補助関数に渡す
== や === の結果も、const で名前を付けて保存できます。
JavaScript
const limit = 5;
const reached = limit === 5;
console.log(reached); // true演習では、結果を決まった形にまとめる補助関数を用意しています。補助関数とは、別の処理を受け持つ関数のことです。カッコの中へカンマで区切って値を渡し、戻り値を受け取ります。次は本の表示文を組み立てる別の例です。
JavaScript
function makeBookLabel(book, copies) {
return book + "を " + copies + " 冊";
}
function bookLabel(book, copies) {
return makeBookLabel(book, copies);
}
console.log(bookLabel("図鑑", 2)); // 図鑑を 2 冊値は書いた順に渡ります。演習の補助関数 packEquality には、ゆるい比較の結果、厳密な比較の結果の順で渡してください。補助関数の中にある {} は、2 つの結果を名前付きでまとめる箱です。この箱の書き方は後の回で学ぶので、演習では補助関数をそのまま使います。
引数を省いて関数を呼ぶと、その引数の値は undefined になります。先ほどの関数でも、2 つ目の copies を省くと次のようになります。
JavaScript
console.log(makeBookLabel("図鑑")); // 図鑑を undefined 冊演習でも 2 つ目の引数が省かれる場合があります。本文の表にある null と undefined の比較を参考にしてください。
よくある間違い
=と==と===を取り違える —=は代入です。比較のつもりでisPinned = trueと書くと、値を書き換えたうえで常に成立する条件ができあがります。等しいかを調べたいときは記号を 3 つ書く、と体に覚えさせてください
JavaScript
let isPinned = false;
console.log(isPinned = true); // true 代入した値がそのまま返る
console.log(isPinned === true); // true こちらが比較- 境界の値を落とす — 「100 以上」を
> 100と書くと 100 ちょうどが漏れます。>=と<=は等号を含む、と毎回声に出して確かめてください
要件
- 関数名は
checkEquality、引数はaとbの 2 つのままにすること aとbを==で比較し、結果をconst looseに保存することaとbを===で比較し、結果をconst strictに保存することpackEqualityにloose、strictの順で渡し、その戻り値を返すこと。2 つの結果はどちらも真偽値bが渡されなければundefinedのまま比較し、別の値に置き換えないこと