MeWrite Docs

TypeError: Cannot read properties of undefined

undefined または null のプロパティにアクセスした場合に発生するエラー

概要

TypeError: Cannot read properties of undefined は、undefined または null の値に対してプロパティやメソッドにアクセスしようとした場合に発生するエラーです。

エラーメッセージ

TypeError: Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of null (reading 'value')
TypeError: undefined is not a function

原因

  1. 未初期化の変数: 変数が undefined のまま使用
  2. API レスポンスの未確認: データ取得前にアクセス
  3. DOM 要素が見つからない: querySelector が null を返す
  4. オブジェクトのネストしたプロパティ: 途中のプロパティが存在しない
  5. 非同期処理のタイミング: データ取得完了前にアクセス

解決策

1. オプショナルチェーン(?.)を使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const user = { name: "Alice" };

// ❌ TypeError
console.log(user.address.city);

// ✅ オプショナルチェーン
console.log(user.address?.city);  // undefined

// ✅ デフォルト値と組み合わせ
console.log(user.address?.city ?? "Unknown");

2. 存在確認してからアクセス

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const data = fetchData();

// ❌ data が undefined の可能性
data.items.forEach(item => console.log(item));

// ✅ 存在確認
if (data && data.items) {
    data.items.forEach(item => console.log(item));
}

// ✅ オプショナルチェーン
data?.items?.forEach(item => console.log(item));

3. DOM 要素の存在確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ❌ 要素が存在しない場合
const button = document.querySelector('#submit-btn');
button.addEventListener('click', handleClick);  // TypeError

// ✅ 存在確認
const button = document.querySelector('#submit-btn');
if (button) {
    button.addEventListener('click', handleClick);
}

// ✅ オプショナルチェーン
document.querySelector('#submit-btn')?.addEventListener('click', handleClick);

4. 配列メソッドの安全な使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const response = { data: null };

// ❌ null に map は使えない
response.data.map(item => item.name);

// ✅ デフォルト値を設定
(response.data || []).map(item => item.name);

// ✅ nullish coalescing
(response.data ?? []).map(item => item.name);

5. 関数の引数チェック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// ❌ 引数が undefined の可能性
function processUser(user) {
    return user.name.toUpperCase();
}

// ✅ デフォルト引数
function processUser(user = {}) {
    return user.name?.toUpperCase() ?? "UNKNOWN";
}

// ✅ 引数の検証
function processUser(user) {
    if (!user || !user.name) {
        throw new Error("User with name is required");
    }
    return user.name.toUpperCase();
}

6. async/await での安全なアクセス

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// ❌ レスポンスの確認なし
async function getUser(id) {
    const response = await fetch(`/api/users/${id}`);
    const data = await response.json();
    return data.user.name;  // TypeError の可能性
}

// ✅ レスポンスを確認
async function getUser(id) {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
        throw new Error('User not found');
    }
    const data = await response.json();
    return data?.user?.name ?? "Unknown";
}

7. 状態管理での初期値

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// React での例
// ❌ 初期値が undefined
const [user, setUser] = useState();
return <div>{user.name}</div>;  // TypeError

// ✅ 初期値を設定
const [user, setUser] = useState({ name: "" });
return <div>{user.name}</div>;

// ✅ または条件付きレンダリング
const [user, setUser] = useState(null);
return user ? <div>{user.name}</div> : <div>Loading...</div>;

8. 配列の分割代入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const data = {};

// ❌ items が undefined
const [first, second] = data.items;

// ✅ デフォルト値
const [first, second] = data.items || [];

// ✅ オプショナルチェーン + nullish coalescing
const [first, second] = data?.items ?? [];

9. コールバック関数のチェック

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function executeCallback(callback) {
    // ❌ callback が undefined の可能性
    callback();
}

// ✅ 関数かどうか確認
function executeCallback(callback) {
    if (typeof callback === 'function') {
        callback();
    }
}

// ✅ オプショナルチェーン
function executeCallback(callback) {
    callback?.();
}

デバッグのコツ

console.log で値を確認

1
2
3
4
5
6
7
8
9
async function processData(input) {
    console.log('input:', input);  // 値を確認
    console.log('type:', typeof input);  // 型を確認

    const result = input?.data?.items;
    console.log('result:', result);

    return result;
}

try-catch で詳細を取得

1
2
3
4
5
6
try {
    const name = user.profile.name;
} catch (e) {
    console.error('Error:', e.message);
    console.error('User object:', user);
}

JavaScript の他のエラー

最終更新: 2025-12-08