2026.09.23 泊まれる場所4,223 立ち寄りスポット59,693 営業中を確認したキャンプ場1,005 note を読む

JavaScriptの==と===の違い|"0"==falseはtrue、0==nullはfalseになる

JavaScriptの==は、型が違うと変換してから比べる。===は型が違えばfalse。
==が裏でやっている変換の順番と、フォームの値を比べるときの取り違えをMDNの説明で整理した。

JavaScriptの == と === の違いは、比べる前に型をそろえるかどうか、の一点だ。
== は型が違うと片方を変換してから比べるので、"0" == false も null == undefined も true になる。
=== は型が違った時点で false を返す。
この記事では、MDN の説明をもとに、== が裏でやっている変換の順番と、フォームの値を比べるときに起きやすい取り違えを整理する。

仕様の説明は、どれも MDN に書いてあることだ。
「僕は〜と思う」と書いたところだけが、僕の意見になる。

まず結果だけ並べてみる

MDN の例から、== で true になる組み合わせを抜き出すと、こうなる。

"1" == 1;           // true
0 == false;         // true
null == undefined;  // true
0 == null;          // false
[1, 2, 3] == "1,2,3"; // true

"1" === 1;          // false
0 === false;        // false
null === undefined; // false

上の段が ==、下の段が同じ組み合わせを === で比べたものだ。
同じ値どうしなのに、演算子を1文字変えただけで答えが逆になる。
0 == null だけが false なのも、ぱっと見では理由が分からない。

==が裏でやっている変換の順番

MDN は、== の動きをおおまかに次の順で説明している。
上から順に当てはめて、当てはまったところで答えが決まる。

1. 型が同じなら、そのまま比べる

数値どうし、文字列どうしなら、変換はしない。
この段階では === と同じ動きになる。
ただし NaN はどちらの演算子でも、自分自身とも一致しない。

2. 片方がnullかundefinedなら、もう片方もnullかundefinedのときだけtrue

null == undefined が true になるのは、この決まりのせいだ。
そして 0 == null が false になるのも、同じ決まりのせいだ。
null は数値に変換されずに、ここで判定が終わる。

3. 片方がオブジェクトなら、プリミティブに変換する

配列もオブジェクトなので、文字列と比べると先に文字列へ変換される。
[1, 2, 3] は "1,2,3" になるので、[1, 2, 3] == "1,2,3" は true になる。
逆に、オブジェクトどうしは中身ではなく「同じものを指しているか」で比べるので、中身が同じ配列を2つ作って == で比べても false になる。

4. 真偽値は数値に、文字列は数値に直してから比べる

最後の段で、真偽値は true が1、false が0に変換される。
数値と文字列なら、文字列のほうが数値に変換される。
"0" == false は、false が0になり、"0" も0になるので true になる。
数値にできない文字列は NaN になり、NaN は何とも一致しないので false になる。

MDN は、=== は実質この1番だけを行って、それ以外は全部 false を返す、と説明している。
覚える量の差は、ここにある。

フォームの値を比べるときに起きる取り違え

この違いがいちばん効いてくるのは、入力欄の値を比べるときだと思う。
input 要素の value は、type="number" の欄でも文字列で返ってくる。

// 数量の欄に 0 と入力されたとする
const qty = document.querySelector("#qty").value; // "0"(文字列)

qty === 0;  // false(型が違う)
qty == 0;   // true("0" を数値に直してから比べる)
qty == false; // true

=== に書き換えただけだと、今まで通っていた判定が急に通らなくなる。
かといって == のままだと、空欄の "" も 0 == "" で true になり、「0と入力された」と「何も入力されていない」の区別がつかない。

僕は、比べる前に自分で型をそろえてから === で比べるのがいちばん読みやすいと思う。
数値の欄なら、MDN にある valueAsNumber を使うと、最初から数値で受け取れる。
数値にできないときは NaN が返るので、空欄はそこで弾ける。

const qty = document.querySelector("#qty").valueAsNumber;

if (Number.isNaN(qty)) {
  // 空欄、または数値にできない入力
} else if (qty === 0) {
  // 0 と入力された
}

NaN を === で判定できない話は、NaNが自分自身と一致しない記事に書いた。
文字列のまま数値を扱って起きる別の取り違えは、並び替えで100が2より先に来た記事にある。

==をあえて使う場面はあるか

MDN の説明どおりなら、x == null は x が null か undefined のときだけ true になる。
2つまとめて判定したいときに、この書き方を使うコードはよく見かける。

ただ、僕は x === null || x === undefined と書くか、?? のような専用の書き方に寄せるほうが好きだ。
読む人が == の変換の順番を思い出さなくて済むからだ。
チームで書くなら、どちらに寄せるかを決めておくのがいちばん効くと思う。

まとめ

  • == は型が違うと変換してから比べる。=== は型が違えば false
  • null と undefined は == でお互いにだけ一致し、0 や "" とは一致しない
  • 真偽値は1と0に、文字列は数値に直してから比べられる。だから "0" == false は true
  • 入力欄の value は文字列。valueAsNumber などで型をそろえてから === で比べる

出典

まる子パパ

まる子パパ

会社員。受託開発のエンジニアを15年以上続けていて、その前は寿司職人・長距離運転手・農業。 技術ブログは、キャンプの合間に踏んだバグと、AI・Web開発の運用の失敗を書いています。 このサイト自体が、開発に携わっているCMS「コンテナ」の稼働中の実例です。 このサイトについて / 小さな自動化の相談

—

ほかにも書いています

受託・note・スタンプ

※受託の相談とnoteは、運営者が個人で受けている・書いているものです。

技術ブログ一覧へ戻る