記事内にはプロモーションが含まれています

【JavaScript】nullとundefinedの違いは?正しい判定方法やモダンな演算子の使い方

【JavaScript】nullとundefinedの違いは?正しい判定方法やモダンな演算子の使い方 JavaScript

JavaScriptを学習していると、必ずと言っていいほど混乱するのが nullundefined の存在です。

どちらも「値がない」ことを表すように見えますが、明確な違いがあり、正しく使い分けないと予期せぬバグの原因になります。

「変数が定義されていないエラーが出た」
「if文で判定したら、0や空文字まで弾かれてしまった」

こうしたトラブルを防ぐためには、両者の性質と判定ロジックを正しく理解する必要があります。

この記事では、nullundefined の意味的な違いから、実務で推奨される判定テクニック、そしてES2020以降で標準となった便利な演算子(???.)まで、現在の開発トレンドに合わせて徹底解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

null と undefined の決定的な違い

どちらも「無」を表すプリミティブ値ですが、発生するシチュエーションと意味合いが異なります。

一言で言えば、「自然発生する無(undefined)」か、「意図的に作られた無(null)」かという違いがあります。

undefined:値が「未定義」である状態

undefined は、変数が宣言されたものの、まだ値が代入されていない状態を表します。

また、オブジェクトに存在しないプロパティへアクセスした場合や、戻り値のない関数の結果も undefined になります。

let user;
console.log(user); // undefined(変数はあるが値がない)

const obj = { name: "Tanaka" };
console.log(obj.age); // undefined(プロパティが存在しない)

function doNothing() {}
console.log(doNothing()); // undefined(戻り値がない)

let user; と宣言した時点で、JavaScriptエンジンによって自動的に undefined という値が割り当てられます。

つまり、プログラマーが明示的に書かなくても「システム側が設定する初期値」というニュアンスが強いのが特徴です。

null:値が「空(から)」である状態

null は、変数は定義されているが、そこに「有効な値が存在しない」ことを明示的に表すために使われます。

undefined と違い、プログラマーが意図して代入しない限り、勝手に null になることはほとんどありません。

let selectedItem = null; // 初期値として「何もない」をセット

// 処理の結果、該当データがなかった場合など
const result = findUser("unknown_id");
if (result === null) {
    console.log("ユーザーが見つかりませんでした");
}

「まだ選択されていない」「検索したが結果がなかった」といった、意図された不在を表現する際に null を使います。

データベースからの取得結果が空の場合なども、一般的に null が返されることが多いです。

typeof 演算子での挙動の違い(重要)

型を調べる typeof 演算子を使った場合、両者には歴史的な違いがあります。

console.log(typeof undefined); // "undefined"
console.log(typeof null);      // "object"

typeof null"object" を返すのは、JavaScriptの初期仕様からの有名なバグ(仕様)です。

修正すると多くの既存コードが動かなくなるため、現在もそのままになっています。

そのため、null かどうかを判定する際に typeof を使うのは非推奨です。

正しい判定方法:等価演算子(==)と厳密等価演算子(===)

nullundefined を判定する際、==(緩やかな比較)を使うか ===(厳密な比較)を使うかで結果が異なります。

ここがバグを生みやすいポイントなので、しっかり押さえておきましょう。

厳密等価演算子(===)で区別する【推奨】

それぞれの値を厳密に区別したい場合は、=== を使用します。

const value = null;

console.log(value === null);      // true
console.log(value === undefined); // false

型まで含めて比較するため、nullnull とだけ一致し、undefined とは一致しません。

基本的には、意図しない挙動を防ぐために常に === を使うことが推奨されます。

等価演算子(==)でまとめて判定するテクニック

一方で、「null または undefined のどちらかであれば弾きたい(値がないとみなしたい)」というケースも多々あります。

その場合は、あえて == を使うテクニックがあります。

const val1 = null;
const val2 = undefined;

// null または undefined かどうかを判定
if (val1 == null) {
    console.log("val1はありません"); // 表示される
}

if (val2 == null) {
    console.log("val2はありません"); // 表示される
}

JavaScriptの仕様では null == undefinedtrue となります。

そのため、if (value == null) と書くだけで、nullundefined の両方を一度にチェックできます。

ただし、チームのコーディング規約で == の使用が禁止されている場合もあるため、その際は if (value === null || value === undefined) と書きましょう。

空文字や0との違い(falsyな値)

JavaScriptの if 文では、nullundefined 以外にも false とみなされる値(falsyな値)があります。

これらを混同すると、「数値の0を入力したのにエラー扱いになった」といったバグにつながります。

falsyな値の一覧

以下の値は、if文の条件式に入れると false として扱われます。

  • false
  • null
  • undefined
  • 0(数値のゼロ)
  • -0
  • 0n(BigInt)
  • ""(空文字)
  • NaN(非数)

危険な判定例

const score = 0; // 点数が0点

// やってはいけない判定(0もfalse扱いになる)
if (!score) {
    console.log("点数が未入力です");
}

score0 が入っている場合、それは「有効な値」ですが、if (!score)true になってしまい、「未入力」と誤判定されます。

値が 0""(空文字)の場合も有効な値として扱いたい場合は、次項で紹介するモダンな演算子が役立ちます。

モダンな判定テクニック(?? と ?.)

ES2020で導入された2つの演算子を使うと、nullundefined だけをターゲットにした安全な処理が簡単に書けるようになりました。

現在の開発現場では必須の知識です。

Null合体演算子(??)でデフォルト値を設定する

?? 演算子は、左側の値が null または undefined の場合のみ、右側の値を返します。

0"" は有効な値としてそのまま使われます。

const score = 0;
const message = "";
const noValue = null;

// || 演算子だと 0 や "" も弾かれる(従来の悩み)
console.log(score || "未設定");   // "未設定"
console.log(message || "未設定"); // "未設定"

// ?? 演算子なら null/undefined だけを弾く
console.log(score ?? "未設定");   // 0
console.log(message ?? "未設定"); // ""(空文字)
console.log(noValue ?? "未設定"); // "未設定"

これまでデフォルト値の設定に使われていた ||(OR演算子)の欠点を解消したのが ?? です。

「値が入っていない時だけデフォルト値を使いたい」という場面では、迷わず ?? を使いましょう。

オプショナルチェーン(?.)で安全にアクセスする

?. 演算子は、オブジェクトのプロパティにアクセスする際、途中のプロパティが nullundefined であってもエラーにならず、undefined を返してくれます。

const user = {
    profile: null // 詳細情報がない
};

// 従来の方法:エラーになるか、冗長なチェックが必要
// console.log(user.profile.age); 
// -> TypeError: Cannot read properties of null

// オプショナルチェーンを使用
console.log(user.profile?.age); // undefined(エラーにならない)

// 配列や関数呼び出しにも使える
const users = null;
console.log(users?.[0]); // undefined

user.profilenull の状態で .age にアクセスしようとすると、通常はプログラムがクラッシュします。

しかし ?. を使えば、「もし user.profile があれば age を取得、なければそこで終了して undefined を返す」という処理を簡潔に記述できます。

APIレスポンスなど、データ構造が不確定な場合やネストが深い場合に非常に強力です。

JavaScriptのスキルを活かして年収を上げる方法

以上、JavaScriptのnullとundefinedの違いについて詳しく解説してきました。

なお、JavaScriptのスキルがある場合には、「副業で稼いで年収を上げる」といったことが可能です。

JavaScriptのスキルを持つ人は多いものの、その分案件数も多く、副業エージェントやフリーランスエージェントを利用することで予想外の高単価案件が見つかることもあります。

エージェントサービスは、登録も利用もすべて完全無料なので、どんな求人や案件があるのか気になる方は、気軽に利用してみるとよいでしょう。