JavaScript

JavaScriptの「Cannot read properties of undefined」エラーの原因と安全な対処法

JavaScriptでプロパティ参照時に発生する「Cannot read properties of undefined」の原因を、具体例と出力結果で確認し、安全な書き方やデバッグ方法を解説する。

この記事でわかること

  • エラーは、undefinedになっている値のプロパティやメソッドを読もうとしたときに発生する。
  • 原因の特定には、エラー行だけでなく参照対象の値がどこで作られたかを確認する。
  • Optional Chainingや条件分岐を使い分け、値が存在しない場合の処理を明確にする。

エラーメッセージの意味を読み解く

「Cannot read properties of undefined」は、undefinedになっている値からプロパティやメソッドを読み取ろうとしたときに発生する代表的なTypeErrorです。V8系の環境では、読み取ろうとしたプロパティ名を含む形式で表示されることがあります。実際の文言や表示位置は、ブラウザーやNode.jsなどの実行環境によって異なります。

JavaScript
const user = undefined;

console.log(user);
// 出力例: undefined

console.log(user.name);
// 代表的なエラー例:
// TypeError: Cannot read properties of undefined (reading 'name')

ポイントは、user自体を表示する処理と、user.nameのようにundefinedのプロパティを参照する処理では結果が異なることです。

undefinedになる代表的な原因を確認する

値がundefinedになる原因には、初期化前の参照、存在しないプロパティや配列要素へのアクセス、値を返さない関数などがあります。

JavaScript
const user = {};
console.log(user.name);
// 出力例: undefined

const users = [{ name: 'Aki' }];
console.log(users[1].name);
// エラー例: users[1] が undefined のため、name を読めない

function createUser() {
  // return がないため、戻り値は undefined
}

const createdUser = createUser();
console.log(createdUser.name);
// エラー例: createdUser が undefined

APIレスポンスや非同期処理では、データ取得前に参照していないか、実際のレスポンス構造と想定が一致しているかを確認します。調査時は、エラー行の参照対象を一時的に表示し、その値の生成箇所までさかのぼると原因を切り分けやすくなります。

JavaScript
console.log('参照前の値:', user);
console.log(user.name);

条件分岐で値の存在を確認する

値が存在する場合だけ処理するなら、条件分岐で明示的に確認できます。必須データが欠けたときにエラーを通知したい場合にも適しています。

JavaScript
const user = undefined;

if (user && user.name) {
  console.log(user.name);
} else {
  console.log('ユーザー名がありません');
}
// 出力: ユーザー名がありません

const name = user && user.name || '名前なし';
console.log(name);
// 出力: 名前なし

代替値には||と??を使い分けます。||は空文字、0、falseも代替値に置き換えます。一方、??はnullまたはundefinedの場合だけ右辺を使います。

Optional Chainingで安全にプロパティを参照する

Optional Chainingの?.を使うと、途中の値がnullまたはundefinedの場合にエラーを発生させず、undefinedを返せます。ネストしたデータを短く参照したい場合に便利です。

JavaScript
const user = undefined;

console.log(user?.name);
// 出力: undefined

console.log(user?.profile?.email ?? 'メールアドレスなし');
// 出力: メールアドレスなし

const count = 0;
console.log(count || 10);
// 出力: 10

console.log(count ?? 10);
// 出力: 0

ただし、Optional Chainingはデータの欠落原因を解決する機能ではありません。値がない状態を許容して処理を継続する記法なので、必須データが欠けた場合は条件分岐でエラーを通知するなど、要件に合わせて使います。

書き方特徴向いている場面
通常のドット記法値がないとエラーになる値が必ず存在する設計
条件分岐欠落時の処理を明示しやすい必須データの検証やエラー通知
Optional Chaining欠落時にundefinedを返す省略可能なデータの参照
値がない場合の書き方の使い分け

エラーを再発させない設計とデバッグの進め方

まず、APIや関数の戻り値について、必ず存在する値と欠ける可能性がある値を整理します。そのうえで、データ取得後に処理を開始する、初期値を用意する、必要な値がなければエラーとして通知する、といった方針を決めます。

デバッグでは、エラー行だけを修正するのではなく、参照対象がどこでundefinedになったかを確認することが重要です。Optional Chainingで黙って処理を続けるのか、条件分岐で異常を検知するのかを、データの重要度に応じて選択しましょう。

参考