ポイントを押さえつつ、実際に動かして確認できるコード例と「注意したい落とし穴」を交えて進めます。最後に短い確認問題(解答つき)も付けます。
何を比べているの?(ざっくり)
JavaScript では「値が等しいか?」を調べる方法が主に2種類あります。
==(等価演算子)
→ 型が違えば自動で型変換してから比較する。ちょっと“やさしい”けど予想外の結果が出ることがある。===(厳密等価演算子)
→ 型も値も同じかどうかをそのまま比較する。変換しないので予想しやすい。
初心者はまず === を基本に使うと安心です。
仕組み(もう少しだけ深掘り)
===(厳密等価)
- 型が違えば即
false。 - 型も同じなら、その型ごとのルールで比較(数なら数値比較、文字列なら文字列比較)。
- 例外:
NaN === NaNは false(特別扱い)。Object.is(NaN, NaN)を使うとtrue。
==(等価) の主な変換ルール(要点)
比較する前に 片方または両方の値が「プリミティブ(数・文字列・真偽値・null・undefined)」でない場合、オブジェクトはプリミティブに変換される(valueOf() / toString() の結果)。
その他よく出るルールだけ抜粋:
null == undefined→true(これだけの特別ルール)- 数値と文字列 → 文字列を数に変換して比較(例:
10 == '10'→true) - 真偽値(boolean) → 数に変換(
true→1,false→0) - オブジェクトとプリミティブ → オブジェクトをプリミティブに変換してから比較
- 例:配列
[]は''に、[1]は'1'に変換されやすい(配列のtoString()の振る舞い)。
- 例:配列
等価演算(== と !=)と厳密等価演算(=== と !==)の違い — 超かんたんまとめ
===/!==(厳密等価):型も値も同じかをチェックする。型が違えばすぐfalse。==/!=(等価(抽象等価)):型が違えば自動で「型変換」してから値を比べる。便利なときもあるが、予期せぬ結果になりやすい。
初心者へのおすすめ:普段は === / !== を使っておけば混乱が減ります。
具体例(コードと出力) — 一つずつ見ていきましょう
数値と文字列
console.log(10 == '10'); // true
console.log(10 === '10'); // false
JavaScript説明:== は '10' を数値 10 に変換して比較する( = true)。=== は型が違うので false。
null と undefined
console.log(null == undefined); // true
console.log(null === undefined); // false
JavaScript説明:== では null と undefined は特殊に「等しい」と扱われます。型までは一致していないので === は false。
ブール値(true/false)が絡む場合
console.log(true == 1); // true
console.log(true === 1); // false
JavaScript説明:== は true を数値 1 に変換して比べます(true -> 1)。=== は型が違うので false。
空文字列・数値のトリッキー例
console.log('' == 0); // true
console.log('' === 0); // false
JavaScript説明:空文字列 '' が数値に変換されると 0 になるため == では等しい扱いになります。
配列・オブジェクト(参照の比較)
console.log({} === {}); // false
let a = {};
let b = a;
console.log(a === b); // true
console.log([1] == 1); // true
console.log([1] === 1); // false
JavaScript説明:オブジェクト(配列もオブジェクト)は 「参照」 を比較します。別々に作った {} は中身が同じでも別オブジェクトだから === は false。ただし同じ変数を参照していれば true。配列が比較されるときは、まずプリミティブ(文字列など)に変換されてから比較されることがあります([1] → '1' → 数値 1 に変換されて比較されるケースがある)。
NaN(Not-a-Number)の特殊さ
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
JavaScript説明:NaN は === でも == でも自分自身と等しくない(false)扱い。NaN を正しく判定するなら Number.isNaN(value) を使うのが推奨。Object.is は NaN を正しく同一視します(ただし Object.is(+0, -0) の扱いは異なる — 後述)。
-0 と +0 の違い(特殊)
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
JavaScript説明:=== では +0 と -0 は同じと見なされるが、Object.is は区別します(珍しいケースですが知っておくと役立つ)。
等価比較(==)で行われる主な「型変換」のルール(初心者向けに要点)
- 比較される片方が文字列で片方が数値なら、文字列を数値に変換して比較(例:
'10'→10)。 - 比較にブール値が含まれると、ブールは数値に変換される(
true -> 1,false -> 0)。 - オブジェクト(配列も含む)はプリミティブ(文字列や数値)に変換されてから比較される(
[1]→'1')。 nullとundefinedは互いに等しい(null == undefinedがtrue)が、他の値とは等しくならない(例:null == 0はfalse)。
注意:上のルールは 概念 だけ抑えておけばOK。細かいケースは複雑なので、慣れないうちは
===を使うのが安全です。
よくある「罠」・トラップ(実務でもハマりやすい)
0 == ''はtrue(空文字が0に変換される) ⇒ 予期せぬ真偽値を招く。[] == ''はtrue(配列[]が空文字列に変換される)。[] == ![]はtrue(![]がfalse、[]が''に変換されて'' == 0となる) — とてもトリッキー。NaNの比較は特殊:NaN === NaNはfalse(Number.isNaN()を使う)。
これらのため、== の使用は要注意。ほとんどのコードベースでは === を標準にしています。
Object.is と Number.isNaN の補足
Object.is(x, y)は===とほぼ同じだが、NaNをNaNと等しいと判定する点や+0/-0を区別する点で違います。Number.isNaN(value)は「その値が NaN であるか」を安全に判定できます(古いisNaN()は文字列などを数値に変換してしまうので注意)。
実践的なルール(初心者向けの推奨)
- 基本は
===/!==を使う(型チェックが自動で入るため安全)。 ==を使うのは「型変換の挙動を理解したうえで、明確な理由があるときだけ」。NaNを扱う場合はNumber.isNaN()、特殊な同値性が必要ならObject.is()を検討する。- オブジェクトや配列の比較は「参照が同じか」を比較する点を意識する(中身が同じでも別オブジェクトなら
===はfalse)。
練習問題
各式の結果を予想してから答えを見てください。
5 == '5'0 == false'' == falsenull == 0[] == 0[1,2] == '1,2'NaN === NaN{} === {}let x = {}; let y = x; x === yObject.is(+0, -0)
解答と簡単な解説
true—'5'は数値に変換される。true—false->0として比較。true—''->0、false->0のため等しい。false—nullは==でundefinedとだけ等しい(null == 0はfalse)。true—[]->''->0になり0 == 0。true—[1,2]は'1,2'に変換されるので等しい。false—NaNは自分自身と等しくない(Number.isNaN()を使う)。false— 別々に作ったオブジェクトは参照が違うため。true—xとyは同じオブジェクトを参照している。false—Object.isは+0と-0を区別する。
まとめ
- 結論:ほとんどの場合は
===/!==を使おう。 - 等価演算子
==は便利だが「JS の型変換ルール」を理解していないとバグの元。 NaN、+0/-0、オブジェクト参照の比較などの特殊ケースはObject.isやNumber.isNaNが役に立つ。
