目次
nullとundefinedの違いをきちんと理解するために調べました。
初心者でも「なんとなく」ではなく正確に理解しておかないと、いざ問題が起きたときに適切な判断ができません。また、nullやundefinedの扱いを誤ると、プログラムがクラッシュしてサービスが停止するリスクがあります。本記事では、違いを正確に理解した上で、具体的な対処法まで紹介します。
例で理解するnullとundefinedの違い
宅配便を例に考えてみます。APIからデータを取得する場面と照らし合わせながら読んでみてください。
undefined(未定義)は「宅配便がまだ届いていない」状態
荷物を注文したけど、まだ届いていない状態です。荷物があるかないか以前に、そもそも手元に届いていません。
null(空)は「宅配便は届いたけど、箱の中身が空だった」状態
荷物は届きました。でも開けてみたら何も入っていませんでした。「空であること」が確定しています。
この違いが分かると、エラーメッセージの意味も理解しやすくなります。
JavaScriptでの具体例
コードで見てみます。
// undefined: 変数を宣言したけど、値を入れていない
let myPackage;
console.log(myPackage); // undefined
// null: 意図的に「空」を設定した
let emptyBox = null;
console.log(emptyBox); // null
undefinedは「まだ何も設定していない」状態で、nullは「意図的に空にした」状態です。
エラーが起きる仕組み
よくあるエラーを見てみます。
let user; // undefinedの状態
// ユーザーの名前を取得しようとする
console.log(user.name); // エラー!
このコードを実行すると以下のエラーが出ます。
TypeError: Cannot read properties of undefined (reading 'name')
このエラーは「undefinedから name というプロパティを読もうとした」という意味です。宅配便の例で言えば「届いていない荷物の中身を確認しようとした」ようなものです。
なぜチェックが必要なのか
APIからデータを取得する場合を考えます。
// APIからユーザー情報を取得
const response = await fetch('/api/user/123');
const user = await response.json();
// ユーザーの住所を表示
console.log(user.address.city); // ユーザーが住所を登録していなかったら?
ユーザーが住所を登録していない場合、 user.address は undefined になります。そこから city を取得しようとするとエラーになります。
これは「相手が住所を教えてくれるとは限らない」という現実を反映しています。外部から受け取るデータは、期待通りの形式でない可能性が常にあります。
このエラーが発生すると、アプリケーションがその場でクラッシュし、画面が真っ白になったり、処理が途中で止まったりします。ユーザーにとってはサービスが使えなくなる深刻な問題につながります。
モダンな対策方法
問題がきちんと理解できたところで、実際にどのように対処すればいいかを紹介します。
Optional Chaining(オプショナルチェイニング)
?. を使うと、途中でundefinedやnullがあっても安全にアクセスできます。「安全にアクセスできる」とは、undefinedやnullの場合でもエラーを発生させずに処理を続けられるという意味です。
// 従来の書き方
if (user && user.address && user.address.city) {
console.log(user.address.city);
}
// Optional Chainingを使った書き方
console.log(user?.address?.city); // undefinedが返る(エラーにならない)
?. は「もし値があれば次に進む、なければundefinedを返す」という動作をします。
Nullish Coalescing(NULL合体演算子)
?? を使うと、nullまたはundefinedの場合にデフォルト値を設定できます。日本語では「Null合体演算子」と呼ばれることもあります。
// ユーザー名がなければ「ゲスト」を使う
const displayName = user?.name ?? 'ゲスト';
console.log(displayName); // ユーザー名があればそれを、なければ「ゲスト」を表示
|| との違い
似た演算子に || がありますが、動作が異なります。
const count = 0;
// || は 0 や 空文字 もfalseとして扱う
console.log(count || 10); // 10 (0がfalseとして扱われた)
// ?? は null と undefined だけを対象にする
console.log(count ?? 10); // 0 (0はそのまま使われる)
「0」や「空文字」を有効な値として扱いたい場合は ?? を使います。
実践的なチェックパターン
ここまでの内容を踏まえて、実際によく使うチェックパターンを紹介します。
配列の安全なアクセス
const posts = response?.data?.posts ?? [];
// 投稿があれば表示、なければメッセージを表示
if (posts.length > 0) {
posts.forEach(post => console.log(post.title));
} else {
console.log('投稿がありません');
}
関数の引数チェック
function greet(name) {
// 引数がない場合のデフォルト値
const displayName = name ?? 'ゲスト';
console.log(`こんにちは、${displayName}さん!`);
}
greet('田中'); // こんにちは、田中さん!
greet(); // こんにちは、ゲストさん!
greet(null); // こんにちは、ゲストさん!
参考情報
Optional ChainingとNullish Coalescingは、ES2020(2020年)でJavaScriptに追加された比較的新しい機能です。モダンなブラウザやNode.js 14以降であれば問題なく使えます。
nullとundefinedのチェックは、エラーを防ぐための「防御的プログラミング」の基本です。ただし、どこでもチェックを入れればいいわけではありません。null対策には他にもTypeScriptのstrict modeやResult型パターンなどがあります。詳しくは以下の記事も参考にしてください。
