null / undefined
null / undefined
JavaScriptでは、nullとundefinedは別々の特別な値です。nullは値がないことを明示する際によく使い、undefinedは未代入の変数や存在しないプロパティなどで現れます。どちらも値そのものであり、変数が宣言されていない状態とは区別します。
🐾 猫で例えると?
眠そうで返事をしない茶トラを「情報が得られない」イメージに重ねます。ただし返事がないだけでnullかundefinedかは決まりません。たとえば「相棒はいない」と明示してnullを入れるのか、項目自体がなくundefinedになるのかは、データの設計で決めます。
💻 プログラミング現場における「null / undefined」とは?
JavaScriptやTypeScriptでは、nullとundefinedの違いを踏まえて、値がない場合を扱う必要があります。どちらも値がない場面に登場しますが、別の値なので、比較や初期値の扱いをそろえる必要があります。
letで宣言して未代入ならundefinedですが、宣言されていない変数を通常の式で読むとReferenceErrorになります。一方、nullやundefinedのプロパティを直接読もうとするとTypeErrorです。エラーの種類を見ると、名前が見つからないのか、値がないのかを切り分けられます。
⚠️ null / undefinedの仕組みと注意点
JavaScriptにおける有名な罠として、型判定(typeof)の仕様があります。undefinedの型はそのまま"undefined"ですが、nullの型はなぜか"object"(オブジェクト)と判定されてしまうのです。これは言語の歴史的なバグと言われていますが、後方互換性のために今でもそのまま残っています。
JavaScript / TypeScriptでの比較の罠
これらを比較する際、等価演算子(==)と厳密等価演算子(===)で挙動が変わるため、現場では注意が必要です。
// JavaScript / TypeScriptでの例
let ameshoData; // 宣言しただけで代入していない
console.log(ameshoData); // undefined (未定義)
let chatoraSnack = null; // 意図的に「空っぽ」を代入
console.log(chatoraSnack); // null (意図的な空)
// 比較時の注意点(ここが現場でバグを生む原因!)
console.log(ameshoData == chatoraSnack); // true (緩い比較だと同じ「無い」扱いにされてしまう)
console.log(ameshoData === chatoraSnack); // false (厳密な比較なら型が違うので別物として判定される) 通常の比較では===を使うと型変換を避けられます。nullとundefinedの両方を対象にする意図でvalue == nullを使う場合もありますが、チームの規約で意図を明確にします。TypeScriptのstrictNullChecksも、実行時の外部データの検証まで代わりに行うものではありません。
🛠️ null / undefinedを賢く使うためのポイント
未設定のデータを扱うときは、初期値、型、条件式での判定方法をそろえます。
- ?.は値がない場合の短絡: 宣言済みのcatに対するcat?.nameは、catがnullかundefinedならundefinedを返します。ただし未宣言の変数の参照や、すべての関数内部の例外を防ぐわけではありません。
- ??と||は用途で選ぶ: count ?? 1はnullとundefinedだけを置き換え、0を残します。count || 1は0や空文字なども置き換えます。「値なし」の範囲を決めてから選ぶと、正しい0を消さずに済みます。
- チーム内でのルールの統一: 「意図的な空」を表現する際、チーム内でnullを使うか、それともすべてundefinedで統一するか(最近はundefined派の現場も増えています)、コーディング規約で明確にしておくことが重要です。
眠そうな茶トラを「値がない」状態に見立てても、0や空文字とは区別します。データを受け取る処理では、未設定と空の値をどう表すかを決めておくと、初期値や入力チェックの食い違いを減らせます。