この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: エラー一覧
SEOタイトル: JavaScript よくあるエラー集と対処

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>JavaScript の頻出エラー</strong>と原因・対処をまとめて把握する</li><li>TypeError 系: <strong>Cannot read properties of undefined / null</strong> → 値の存在確認、Optional Chaining (<code>?.</code>)</li><li>ReferenceError: <strong>x is not defined</strong> → スペルミス / let/const のスコープ / 読み込み順</li><li>SyntaxError: <strong>Unexpected token</strong> → 括弧 / カンマ / JSON.parse 失敗</li><li>デバッグ: <strong>DevTools の Console / Sources / Network</strong> + Source Maps + try/catch</li></ul></td></tr></table>
<h2>JavaScript エラーの分類</h2>

<p>JavaScript のエラーは大きく<strong>シンタックスエラー (構文エラー)</strong> と<strong>実行時エラー</strong>に分かれます。実行時エラーは <code>Error</code> オブジェクトを継承した複数のサブクラスがあります。</p>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>クラス</th><th>意味</th><th>典型例</th></tr></thead>
<tbody>
<tr><td><strong>SyntaxError</strong></td><td>構文として不正</td><td>括弧の閉じ忘れ、JSON.parse 失敗</td></tr>
<tr><td><strong>TypeError</strong></td><td>値の型が予期しない</td><td>undefined のプロパティアクセス、関数でないものを呼ぶ</td></tr>
<tr><td><strong>ReferenceError</strong></td><td>定義されていない変数</td><td>スペルミス、TDZ、グローバル参照</td></tr>
<tr><td><strong>RangeError</strong></td><td>範囲外の値</td><td>再帰深すぎ、Array 長過剰</td></tr>
<tr><td><strong>URIError</strong></td><td>URI 関数の不正</td><td><code>decodeURI('%')</code></td></tr>
<tr><td><strong>EvalError</strong></td><td>eval の不正 (現在ほぼ未使用)</td><td>-</td></tr>
<tr><td>AggregateError</td><td>複数エラー集約</td><td>Promise.any 全 reject</td></tr>
</tbody>
</table>

<h2>頻出エラー 1: Cannot read properties of undefined</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught TypeError: Cannot read properties of undefined (reading &apos;name&apos;)
Uncaught TypeError: Cannot read property &apos;name&apos; of undefined    (旧表記)
Uncaught TypeError: Cannot read properties of null (reading &apos;value&apos;)</code></pre>
<p>最頻出エラー。undefined または null の値に対してプロパティ / メソッドアクセスしようとした場合に発生。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ よくある原因
const user = users.find(u => u.id === 999);  // 見つからない → undefined
console.log(user.name);                       // ❌ TypeError

const el = document.getElementById(&apos;foo&apos;);    // 要素が無い → null
el.value = &apos;x&apos;;                                // ❌ TypeError

// ✅ 対策 1: 存在チェック
if (user) {
  console.log(user.name);
}

// ✅ 対策 2: Optional Chaining (ES2020+)
console.log(user?.name);                      // user が undefined/null なら undefined
console.log(user?.address?.city);             // ネストも安全

// ✅ 対策 3: デフォルト値 (Nullish Coalescing)
const name = user?.name ?? &apos;匿名&apos;;

// ✅ 対策 4: 配列メソッドは空配列で代用
const items = data?.items ?? [];
items.forEach(...);                           // 空でも安全</code></pre>
<h2>頻出エラー 2: x is not defined</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught ReferenceError: foo is not defined
Uncaught ReferenceError: $ is not defined          ← jQuery が読まれていない
Uncaught ReferenceError: process is not defined    ← ブラウザで Node 変数を使った</code></pre>
<p>存在しない変数を参照した場合に発生。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ スペルミス
const userName = &apos;taro&apos;;
console.log(usrName);              // ❌ ReferenceError

// ❌ スクリプト読み込み順
// <script src="my-code.js"></script>   ← jQuery より先に読まれている
// <script src="jquery.js"></script>
$(&apos;button&apos;).click(...);            // ❌ $ is not defined

// ❌ let/const の TDZ (Temporal Dead Zone)
console.log(x);                    // ❌ Cannot access &apos;x&apos; before initialization
let x = 10;

// ✅ 対策: スペルチェック、読み込み順、宣言を先に
// jQuery / ライブラリは先に読み込む
// または defer 属性、または DOMContentLoaded 後に実行</code></pre>
<h2>頻出エラー 3: Unexpected token</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught SyntaxError: Unexpected token &apos;}&apos;
Uncaught SyntaxError: Unexpected token in JSON at position 0
Uncaught SyntaxError: Unexpected end of JSON input</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ 括弧 / カンマ不一致
const obj = { a: 1, b: 2, };         // 末尾カンマ→OK (ES2017+)
const arr = [1, 2 3];                // ❌ Unexpected number

// ❌ JSON.parse 失敗
JSON.parse(&apos;hello world&apos;);           // ❌ Unexpected token h
JSON.parse(&apos;&apos;);                       // ❌ Unexpected end
JSON.parse("{&apos;name&apos;:&apos;taro&apos;}");       // ❌ Unexpected token &apos; (シングルクォート不可)

// ✅ try/catch でラップ
function safeParse(text, fallback = null) {
  try {
    return JSON.parse(text);
  } catch (e) {
    console.warn(&apos;JSON parse failed:&apos;, e.message);
    return fallback;
  }
}</code></pre>
<h2>頻出エラー 4: Maximum call stack size exceeded</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught RangeError: Maximum call stack size exceeded</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ 無限再帰
function factorial(n) {
  return n * factorial(n - 1);     // 終了条件なし
}
factorial(5);                        // ❌ スタックオーバーフロー

// ✅ 終了条件
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}

// ✅ 深い再帰はループに変換
function factorialIter(n) {
  let r = 1;
  for (let i = 2; i <= n; i++) r *= i;
  return r;
}</code></pre>
<h2>頻出エラー 5: is not a function</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught TypeError: foo.bar is not a function
Uncaught TypeError: arr.map is not a function    ← arr が配列ではない</code></pre><pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ オブジェクトに map を呼んだ
const data = { items: [1,2,3] };
data.map(x => x * 2);                // ❌ data は配列ではない

// ✅ 正しいプロパティ
data.items.map(x => x * 2);

// ❌ API レスポンス前提が崩れる
const res = await fetch(&apos;/api&apos;);
const json = await res.json();
json.results.map(...);               // ❌ results が undefined

// ✅ デバッグ
console.log(typeof json.results, json.results);
// → object, undefined etc.

// ✅ Array.isArray() で確認
if (Array.isArray(json.results)) {
  json.results.map(...);
}</code></pre>
<h2>頻出エラー 6: Illegal invocation</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Uncaught TypeError: Illegal invocation</code></pre>
<p>主に DOM API のメソッドを <code>this</code> 無しで呼んだ場合。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ コンテキスト消失
const log = console.log;             // この時点では問題ない
log(&apos;hello&apos;);                        // OK (たまたま動く)

const qs = document.querySelector;
qs(&apos;div&apos;);                           // ❌ Illegal invocation (this が document でない)

// ✅ bind
const qs = document.querySelector.bind(document);
qs(&apos;div&apos;);                           // OK

// ✅ アロー関数で包む
const qs = (sel) => document.querySelector(sel);</code></pre>
<h2>頻出エラー 7: CORS 関連</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-text">Access to fetch at &apos;https://api.example.com/foo&apos; from origin
&apos;https://myapp.com&apos; has been blocked by CORS policy:
No &apos;Access-Control-Allow-Origin&apos; header is present on the requested resource.</code></pre>
<p>クロスオリジン HTTP リクエストで、サーバが許可ヘッダを返していない。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// クライアント側だけでは解決不能
// サーバが Access-Control-Allow-Origin を返す必要あり

// 開発時の回避策: プロキシ
// Vite (vite.config.js):
export default {
  server: {
    proxy: {
      &apos;/api&apos;: &apos;https://backend.example.com&apos;
    }
  }
}

// fetch 時の credentials
fetch(url, { credentials: &apos;include&apos; });   // Cookie 送信、サーバ側で Allow-Credentials 必要

// CORS preflight (OPTIONS) が走るリクエスト:
// - Content-Type が application/json
// - カスタムヘッダ付き
// - PUT/DELETE/PATCH</code></pre>
<h2>頻出エラー 8: Promise / async 関連</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ❌ Unhandled Promise Rejection
async function getUser(id) {
  const res = await fetch(`/api/users/${id}`);
  return await res.json();
}
getUser(1);                          // エラー時、未捕捉警告

// ✅ try/catch
try {
  const user = await getUser(1);
} catch (e) {
  console.error(&apos;Failed to load user:&apos;, e);
}

// ✅ .catch
getUser(1)
  .then(u => console.log(u))
  .catch(e => console.error(e));

// ✅ グローバル捕捉
window.addEventListener(&apos;unhandledrejection&apos;, e => {
  console.error(&apos;Unhandled:&apos;, e.reason);
});

// ❌ await を忘れる
async function check() {
  const ok = isAdmin(user);          // Promise を真偽判定 (常に true!)
  if (ok) { ... }
}

// ✅
const ok = await isAdmin(user);</code></pre>
<h2>デバッグの定石</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>ツール</th><th>用途</th></tr></thead>
<tbody>
<tr><td>DevTools Console</td><td>エラー / console.log / 対話実行</td></tr>
<tr><td>DevTools Sources (Debugger)</td><td>ブレークポイント、ステップ実行、変数監視</td></tr>
<tr><td>DevTools Network</td><td>HTTP リクエスト確認 (4xx/5xx, CORS)</td></tr>
<tr><td>Source Maps (.map)</td><td>ミニファイ後でも元コードでデバッグ</td></tr>
<tr><td><code>debugger;</code> 文</td><td>コード中でブレーク</td></tr>
<tr><td><code>console.table()</code></td><td>配列/オブジェクトを表形式</td></tr>
<tr><td><code>console.trace()</code></td><td>スタックトレース</td></tr>
<tr><td><code>console.dir()</code></td><td>オブジェクトの構造表示</td></tr>
</tbody>
</table>

<h2>エラーバウンダリ (実運用)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// グローバルエラーハンドラ
window.addEventListener(&apos;error&apos;, e => {
  reportError(e.error);              // Sentry / Datadog etc.
});

window.addEventListener(&apos;unhandledrejection&apos;, e => {
  reportError(e.reason);
});

// React のエラーバウンダリ
class ErrorBoundary extends React.Component {
  state = { hasError: false };
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    reportError(error, info);
  }
  render() {
    if (this.state.hasError) return <h1>Something broke.</h1>;
    return this.props.children;
  }
}</code></pre>
<h2>FAQ</h2>

<p><strong>Q: try/catch で何でも握りつぶしてよい?</strong><br />
A: NG。エラーは原則「想定済み」のものだけ catch。想定外を catch して空で握りつぶすと、後の不具合が見えなくなります。<strong>少なくとも console.error / 監視サービス通知</strong>を残す。</p>

<p><strong>Q: console.log を本番に残してよい?</strong><br />
A: 情報漏えいやパフォーマンスの観点で削除が定石。ビルドツール (terser / webpack) で本番ビルド時に <code>drop_console</code> オプションで自動削除可能。</p>

<p><strong>Q: TypeScript で防げる?</strong><br />
A: 多くは防げます。<code>strict</code> モードで null/undefined チェック必須化 (<code>strictNullChecks</code>)、未定義変数の検出、型不整合の早期発見など。ただし実行時の API レスポンス型までは保証しないので、zod 等で検証推奨。</p>