🗓️

undefinedとnull、どう使い分ける?

に公開

はじめに

API連携などで、コンソールログやエラーメッセージで頻繁に見かけるundefinedやnull。
正直なところ、以前の私はこれらが出ても「なんとなく値が空なんだろうな」とふんわり解釈し、その違いをしっかり理解しないまま仕事をしていました。
そこで今回はこの2つの違いを「バイトのシフト表」に例えて誰でもわかるように簡単にまとめました。

自己紹介

はじめまして。株式会社Rabeeのフロントエンドエンジニア、dkichiです。
普段の開発の中で「理解がふわっとしているな」「苦手だな」と感じた部分を、自分なりにまとめて解消していこうと思います!

結論

バイトのシフトで例えると以下になります。

  • undefined
    • シフト表が 「空欄」 の状態。
    • 意味:書き忘れ、またはまだ決まっていない。
  • null
    • シフト表に 「休み」 と書いてある状態。
    • 意味:あえて「値がない」ことを確定させている。
  1. undefined:システムが自動で出す「なし」
    Frame 1.png
    JavaScriptの仕組みとして、「中身が定義されていないよ」と自動的に返ってくるのがundefinedです。
let name = "Taro";
let shift;
console.log(shift); // => undefined(名前はあるけどシフトを書いてない)

const user = { name: "Taro" };
console.log(user.shift); // => undefined(shiftという項目自体がない)
  1. null:人間が意図的に入れる「なし」
    Frame2.png
    一方で、開発者が「ここはあえて空ですよ」と明示したいときに代入するのがnullです。
// 1. 当初の予定(一度はシフトが決まった)
let shift = "10:00-19:00";

// 2. やっぱり休みにする
shift = null; 

console.log(shift); // null(意図的な「なし」)

重要:実務ではどう使い分けるべきか?

実は、この2つの使い分けには「正解」がありません。結局、そのプロジェクトのルールを決めた人がどう考えているかがすべてだからです。
とはいえ、最近は「nullを使わずundefinedに統一する」というルールが主流になりつつあります。その裏側には、「バグの芽を摘む」という技術的な理由があります。

パターンA:nullとundefinedを使い分ける
データの整合性を高めることができます。

  • null:データは存在するが、中身が空であると「確定」している。
  • undefined:データが存在するかどうかも「不明」である。

パターンB:undefinedに統一する
「ない」という状態が二種類あること自体がバグの元と考えることが多いです。

  • JavaScriptの挙動に合わせる:JSの仕様上、値がないときは勝手にundefinedが返ってきます。それなら空のときもundefinedと決めてしまったほうが、ルールがシンプルになり、開発者の「どっちを入れるんだっけ?」という迷いをなくせます。
  • 型定義の迷いをなくす(TypeScript):TypeScriptでcomment?: stringと定義すると、型はstring | undefinedになります。ここにnullを許可するとstring | null | undefinedとなり、型チェックのコードが複雑化して、判定漏れのミスを誘発します。

まとめ

  • undefined:
    • 言語仕様としての「未定義」。シフト表の空欄。
  • null
    • 開発者の意図としての「欠損値」。シフト表の「休み」スタンプ。

実務での向き合い方:

  • 最近の主流はundefined統一: 状態を1つに絞ることで、バグの元を減らす設計が好まれています。
  • 正解はプロジェクトのルールにある: 「そのチームがどちらを採用しているか」を揃えることが、最も事故を防ぐ方法です。

「undefinedかnullか」で迷ったときは、まず自分のプロジェクトのコードを眺めてみてください!

undefinedの挙動に関する技術的な深掘りについては、長くなるのでまた別の機会にまとめたいと思います。お楽しみに!

Discussion