よくあるエラーと解決法 - JavaScript

JavaScript で開発していると、何度も同じエラーに遭遇します。よくあるエラーのパターンと解決法を知っておけば、デバッグ時間を大幅に短縮できます。

Cannot read properties of undefined / null

最も遭遇頻度が高いエラーです。undefined や null に対してプロパティアクセスやメソッド呼び出しをすると発生します。

const user = undefined;
console.log(user.name);
// TypeError: Cannot read properties of undefined (reading 'name')

解決法

// オプショナルチェーンを使う
console.log(user?.name);

// 事前にチェックする
if (user) {
  console.log(user.name);
}

// デフォルト値を設定する
const name = user?.name ?? 'ゲスト';

xxx is not a function

関数でないものを関数として呼び出すと発生します。

const num = 42;
num();
// TypeError: num is not a function

const obj = { name: 'Alice' };
obj.getName();
// TypeError: obj.getName is not a function

原因と解決法

変数の上書き

同じ名前の変数で関数を上書きしてしまっていないか確認します。

メソッド名のタイプミス

正しいメソッド名かどうかを確認します。配列で使える forEach を文字列に使おうとしていないか、など。

this の参照先

コールバック内で this が想定と違うオブジェクトを指していることがあります。

xxx is not defined

宣言されていない変数を参照すると発生します。

console.log(undeclaredVariable);
// ReferenceError: undeclaredVariable is not defined

原因と解決法

変数名のタイプミスを確認する
変数の宣言を忘れていないか確認する
スコープの外から参照していないか確認する
import / require を忘れていないか確認する

Unexpected token

構文エラーです。カッコの閉じ忘れ、カンマの付け忘れなどが原因です。

const obj = {
  name: 'Alice'
  age: 30  // カンマ忘れ
};
// SyntaxError: Unexpected identifier 'age'

解決法

エラーメッセージに示された行の前後を確認します。エディタの構文ハイライトやリンターを活用すると、こうしたミスを事前に検出できます。

Assignment to constant variable

const で宣言した変数に再代入しようとすると発生します。

const x = 10;
x = 20;
// TypeError: Assignment to constant variable

解決法

再代入が必要なら let を使います。const のままにしたい場合は、ロジックを見直します。

Cannot use import statement outside a module

ES Modules の import をモジュールでないスクリプトで使うと発生します。

import { something } from './module.js';
// SyntaxError: Cannot use import statement outside a module

解決法

<!-- type="module" を追加 -->
<script type="module" src="main.js"></script>

Node.js の場合は package.json に "type": "module" を追加するか、ファイル拡張子を .mjs にします。

Maximum call stack size exceeded

無限再帰やスタックの深すぎる関数呼び出しで発生します。

function infinite() {
  infinite();
}
infinite();
// RangeError: Maximum call stack size exceeded

解決法

再帰の終了条件を確認します。イベントハンドラ内で自身を呼び出すコードがないかもチェックしましょう。

Uncaught (in promise)

Promise のエラーが catch されていないと発生します。

async function fetchData() {
  throw new Error('取得失敗');
}
fetchData(); // Uncaught (in promise) Error: 取得失敗

解決法

// catch で処理する
fetchData().catch(error => {
  console.error(error);
});

// または try-catch で囲む
async function main() {
  try {
    await fetchData();
  } catch (error) {
    console.error(error);
  }
}

CORS エラー

異なるオリジンへのリクエストがブロックされると発生します。

Access to fetch at 'https://api.example.com' from origin 'http://localhost:3000' 
has been blocked by CORS policy

解決法

サーバー側の設定

API サーバーで適切な CORS ヘッダーを返す設定が必要です。

プロキシを使う

開発環境では、開発サーバーのプロキシ機能を使ってリクエストを中継できます。

これは JavaScript のエラーというよりブラウザのセキュリティ機能ですが、非常によく遭遇します。

エラーメッセージをそのまま検索すると、多くの場合解決策が見つかります。エラーを恐れず、メッセージをしっかり読む習慣をつけましょう。