「== は使うな、必ず === を使え」はほぼ正しいルールです。ただし例外が1つだけあり、それが x == null です。これだけは使ってよい、というのが本記事の主張です。
以前書いた || と ?? の記事(falsy全般とnull/undefinedの違い)、typeof null の記事(null判定にtypeofを使うと事故る話)とは別の切り口で、今回は「null と undefined を1回で判定する書き方として == null を採用してよいか」を扱います。
検証環境は Node.js v24.14.1 です。表示している出力はすべて実際に実行した結果です。
x == null の判定結果を実測する
const values = [
['null', null], ['undefined', undefined], ['0', 0], ["''", ''],
['false', false], ['NaN', NaN], ['[]', []], ['{}', {}], ["'0'", '0']
];
for (const [label, v] of values) {
console.log(label.padEnd(10), 'x == null:', String(v == null).padEnd(5),
'| ===null||===undefined:', String(v === null || v === undefined).padEnd(5),
'| !x:', !v);
}
null x == null: true | ===null||===undefined: true | !x: true
undefined x == null: true | ===null||===undefined: true | !x: true
0 x == null: false | ===null||===undefined: false | !x: true
'' x == null: false | ===null||===undefined: false | !x: true
false x == null: false | ===null||===undefined: false | !x: true
NaN x == null: false | ===null||===undefined: false | !x: true
[] x == null: false | ===null||===undefined: false | !x: false
{} x == null: false | ===null||===undefined: false | !x: false
'0' x == null: false | ===null||===undefined: false | !x: false
x == null が true になるのは null と undefined だけで、x === null || x === undefined と全行一致します。一方 !x は 0 '' false NaN まで true にする(falsyの罠)。== が危険なのは型変換が複雑だからですが、== null が true になる相手は null と undefined の2つだけで、0 や '' との間では型変換が起きません。
?? との使い分け
== null は「判定」、?? は「デフォルト値の代入」で役割が違います(?? と || の違いは上の過去記事で詳しく書きました)。
値を置き換えたいなら ??、null/undefined のときに早期リターンや分岐をしたいなら == null が読みやすい、という整理です。
function greet(name) {
if (name == null) return 'guest';
return name;
}
console.log(greet(null), greet(undefined), JSON.stringify(greet('')), greet('Taro'));
// guest guest "" Taro
空文字は通り、null/undefined だけがguestに倒れます。!name で書くと空文字もguest扱いになります。
ESLintの eqeqeq で例外を許可する
eqeqeq をそのまま有効にすると == null もエラーになります。ESLintのオプションで null だけ無視できます。
// eslint.config.mjs
export default [{
rules: { eqeqeq: ["error", "always", { null: "ignore" }] }
}];
ESLint 9.39.5 で次のコードを検査しました。
const a = 1; const b = null;
console.log(a == b); // 2行目
console.log(a == 2); // 3行目
console.log(a == null); // 4行目
2:15 error Expected '===' and instead saw '==' eqeqeq
3:15 error Expected '===' and instead saw '==' eqeqeq
✖ 2 problems (2 errors, 0 warnings)
2行目(変数どうしの ==)と3行目(数値との ==)はエラーで、4行目の == null だけが通ります。なお ESLint 公式ドキュメントによると、"smart" という別オプションもあり、リテラル同士の比較・typeof の比較・null との比較を許可します。「null だけ」に絞るなら上の書き方です。
typeof x == 'string' も両辺が文字列なので安全ですが、=== に変えても失うものがありません。== null は1回の比較で null と undefined の両方を拾えるという === にはない利点があるので、例外として残す価値があるのはこれだけ、というのが本記事の立場です。
どれを使うか
- チームが「
==禁止」なら、無理に例外を作らずx === null || x === undefinedでも構いません - TypeScript の
strictNullChecksが有効な環境では、型がstring | null | undefinedのような値に対してx == nullでnull | undefinedとそれ以外に絞り込まれます(型の絞り込み=narrowing) - 「値を置き換えたい」なら
??、「falsyを弾きたい(0や空文字も無効)」と本当に決めているときだけ!x
AIが書いたコードで == null を見かけたら
Claude Code などのAIが書いたコードに == null が混ざっていることがあります。機械的に === に直すと、null と undefined の両方を見る意図が片方だけになるバグを生むことがあります。
レビューでは、次の2点を見れば十分です。
- 比較相手が本当に
nullリテラルか(変数との==は別問題) - null と undefined を同じ扱いにしたい意図があるか
== null を「意図のある慣用句」と読めれば、AIの出力を根拠を持って承認・修正できます。ルールは理由まで知って初めて、例外も判断できます。
未経験者向けの講座を運営しています
未経験から Next.js + Supabase + Claude Code で Webアプリを公開するまで を、全24セッションで体系化した教材です。Claude Code を学習パートナーにする CLAUDE.md と学習モード(learner / developer)の設計までセットで含みます。
- ▶ ライブデモ(インストール不要・無料で今すぐ見られます)→ https://trial-web-ayies128s-projects.vercel.app/?ref=qiita
- 教材完全版+月5,500円のメンタリング(全24セッション+チャット質問し放題)→ https://menta.work/plan/20251?ref=qiita
- 無料体験版(git clone して自分の手元で動かす・最初の数セッション分・⭐ Star もよろしくお願いします)→ https://github.com/ayies128/next-ai-camp-trial
- YouTube『AIエンジニア情報局』(AI×開発ニュースを1本5分でキャッチアップできる別運営チャンネル・無料)→ https://www.youtube.com/channel/UC1rXVD9WYsQPQEWZyd-A1KA/?ref=qiita
※ Qiita 読者の方には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。