なぜ == ではなく === を使うのか

== は型を揃えてから比べるため、0 == '' が true になるなど直感と外れます。推移律が成り立たない具体例、== を使ってよい唯一の場面、Object.is との違いを確かめます。

実行して検証済み処理系Node 22.22.3対応ES1難易度●●○○○目安8更新

== は比べる前に型を揃えます。その変換の規則が、覚えきれないほど複雑だからです。

=== は型が違えば即座に false です。規則は1つしかありません。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true false
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true false true

覚えられない、という証明

規則を覚えようとするより、覚える価値が無いことを見たほうが早いです。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true true true true true
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
false false false

0'' は等しい。'''0' は等しくない。なのに 0'0' は等しい。

a == b かつ b == c なのに a == c とは限らない、ではありません。 ここではもっと悪くて、「等しい」が繋がりません

数学の等号なら、a = bb ≠ c なら a ≠ c のはずです。 == はそれを満たしません(推移律が成り立たない)。

繋がらない規則は、頭の中で使えません。

直感から外れる組み合わせ

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true false
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
false false false

配列と文字列が等しくなります。配列が文字列に変換されてから比べられるからです。

=== なら全部 false です。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
無い 無い 0 false
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
無い 無い 無い

== を使ってよい唯一の場面

nullundefined をまとめて判定するときだけです。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
false true
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true false

nullundefined とだけ等しく、他の何とも等しくなりません

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true true
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
true true

だから v == null は「nullundefined のどちらか」を、正確に表します。

0 も空文字も false も、そのまま通っています。 2つ目の出力で 0false のあいだが空いているのは、空文字が出ているためです。

!value で書くと、こうはなりません。

意味のある 0 まで「無い」にされます

?? があるならそちらを使ってください。 value ?? '無い'nullundefined のときだけ右を返します。 == null と同じ判定を、より短く書けます。

=== でも足りないとき

=== にも2つだけ、直感と違うところがあります。

Object.is() はこの2つを直します。

比べ方 NaNNaN 0-0 型変換
== false true する
=== false true しない
Object.is() true false しない
Set / includes true true しない

NaN の話は別ページで詳しく扱っています。 → なぜ NaN === NaN は false なのか

よくある誤解

== のほうが便利」

型を揃えてくれるのは便利に見えます。ですが、揃え方をこちらで選べません。

結果は同じでも、下は何をしているか読めば分かります。 上は「== の規則がたまたまそう動いた」だけです。

変換したいなら、自分で変換してください。文字列を数値に変換する

=== は遅い」

そうではありません。=== は型が違えばそこで終わります。 == のほうが変換の手順を踏むぶん、やることが多くなります。

「文字列と数値を比べたいときは == が要る」

要りません。どちらかに揃えてから === で比べます。

自分で確かめる

上のコードは書き換えて実行できます。

  1. 0 == '\n' を試す(空白だけの文字列はどうなるか)
  2. [] == ![] を試す(両辺が変換される)
  3. null >= 0null == 0 を並べて試す(比較と等価で規則が違う)

予想してから実行してください。 当たらないはずです。

まとめ

  • == は比べる前に型を揃える。その規則が複雑すぎる
  • 0 == ''0 == '0' が真で '' == '0' は偽。「等しい」が繋がらない
  • 使ってよいのは v == null だけ。nullundefined をまとめて見る
  • ただし ?? が使えるならそちらが短い
  • === でも NaN-0 は例外。厳密に見るなら Object.is()
  • 型を揃えたいなら、== に任せず自分で変換する

この記事の根拠

  1. IsLooselyEqual — ECMAScript® 2026 Language Specificationtc39.es
  2. IsStrictlyEqual — ECMAScript® 2026 Language Specificationtc39.es
  3. Object.is — ECMAScript® 2026 Language Specificationtc39.es

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)