作ったページを開いた瞬間、ボタンを押しても何も起きない。スライダーが動かない。フォームが送信できない。原因がさっぱり分からなくて、画面とにらめっこ。JavaScriptを書いていれば、誰もが一度はこの「動かないけど理由が見えない」状態に頭を抱えます。
私はWeb制作を長年やってきましたが、この記事のもとになった古い投稿は、当時のInternet Explorer(IE)で出る「オブジェクトを指定してください」というエラーの話でした。ところがIEは2022年6月15日にサポートが終了し、もはや解決方法を語る対象ですらなくなっています。そこで今回は中身をまるごと作り替え、いまのブラウザで遭遇する一般的なJavaScriptエラーを、原因の見つけ方から直し方まで実例つきで整理し直しました。
この記事を読むと、ブラウザの開発者ツール(DevTools)でエラーメッセージを読み解き、Uncaught TypeError や is not defined といった頻出エラーの正体を見抜き、自分の手で原因を切り分けられるようになります。コンソールの開き方からブレークポイントの使い方、そして現場で本当によく出るエラーの直し方までを、実際のコード例を交えて順番に解説します。
エラーは「読めれば」9割解決したようなものです。逆に言えば、読み方を知らないまま手当たり次第にコードをいじっても、なかなか前に進めません。まずは怖がらずにコンソールを開くところから始めましょう。
関連記事:JavaScriptのasyncとdeferの違い|読み込みを最適化して表示速度を改善
まず押さえる:IEは終わった、デバッグの主役はDevTools
昔のWeb制作では、IE専用のエラー対応が大きな仕事のひとつでした。けれど時代は完全に変わっています。Internet Explorer 11のデスクトップアプリは2022年6月15日にサポートを終了し、2023年2月14日にはMicrosoft Edgeの更新で順次無効化されました。いま私たちがエラーと向き合う相手は、Chrome・Edge・Firefox・Safariといったモダンブラウザです。
これらのブラウザには、共通して強力な「開発者ツール(DevTools)」が備わっています。Windowsなら F12 キー、あるいは Ctrl + Shift + I で開けます(Macは Cmd + Option + I)。ページ上で右クリックして「検証」を選んでも構いません。IE時代の「F12でコンソールを見る」という習慣自体は、実は今もそのまま生きているわけです。
JavaScriptが思いどおりに動かないとき、最初にやることはたったひとつ。DevToolsを開いて「Console(コンソール)」タブを見る、これだけです。赤い文字でエラーが出ていれば、そこに原因のほとんどが書いてあります。私はどんなに焦っていても、まずコンソールを開く。20年以上やってきて、この順番だけは変わりません。
コンソール・ソース・ブレークポイントの使い分け
DevToolsの中で、デバッグに使う主なタブは次の3つです。役割を分けて覚えておくと、無駄に迷わなくなります。
Console(コンソール)は、エラーメッセージと console.log() の出力を確認する場所です。変数の中身を確認したいときは、コードに console.log(変数名) を仕込んで値を覗くのが、一番手軽で確実な方法です。
Sources(ソース)は、読み込まれているJavaScriptファイルの中身を見るタブです。エラーメッセージに表示されたファイル名と行番号をここで開けば、問題の箇所にすぐたどり着けます。
ブレークポイントは、Sourcesタブで行番号をクリックして設定する「一時停止ポイント」です。コードがその行に来た瞬間に実行を止め、その時点での変数の値を一つずつ確認できます。console.log を何十個も書くより、複雑な処理はブレークポイントで止めて追ったほうが早いことが多いです。
出典:ブラウザーの開発者ツールとは? – MDN Web Docs / Internet Explorer 11 – Microsoft Lifecycle
よくあるエラーの正体と直し方
コンソールに出るエラーは、見た目こそ無愛想ですが、実はかなり親切に「何が起きたか」を教えてくれています。ここでは現場で本当によく出会う代表的なエラーを取り上げ、原因と直し方をセットで見ていきます。エラー文の意味さえ分かれば、対処法はだいたい決まってきます。
Uncaught TypeError: Cannot read properties of null(または undefined)
もっとも遭遇率が高いエラーがこれです。意味はシンプルで、「中身が null や undefined のものに対して、プロパティやメソッドを使おうとした」というもの。たとえば、まだ存在しない要素を取得して、その要素を操作しようとしたときに起きます。
const btn = document.getElementById("send");
btn.addEventListener("click", submit);
// → Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
このコードでエラーになる典型的な原因は2つ。ひとつは id 名のタイプミスで、要素が見つからず btn が null になっているケース。もうひとつは、HTMLが読み込まれる前にスクリプトが実行され、まだ要素が存在しないケースです。
後者は、IE時代から続く「読み込み順序」の問題と根っこは同じです。script タグに defer 属性を付けるか、スクリプトを </body> の直前に置けば、要素が用意されてから実行されるようになります。
<script src="main.js" defer></script>
取得できないこと自体を想定するなら、使う前に存在チェックを入れるのも有効です。
const btn = document.getElementById("send");
if (btn) {
btn.addEventListener("click", submit);
}
Uncaught TypeError: x is not a function
「関数として呼び出したけれど、それは関数ではなかった」というエラーです。一番ありがちなのは、メソッド名のタイプミス。たとえば document.getElementByID(...) のように、正しくは getElementById(末尾は小文字の d)であるべきところを大文字で書いてしまうパターンです。
ほかにも、配列用の .map() を通常のオブジェクトに使ってしまった、変数名と関数名がぶつかって上書きされてしまった、といった原因も定番です。エラー文の「x」の部分に出ている名前を、定義した場所と照らし合わせて見直すのが近道です。
Uncaught ReferenceError: x is not defined
こちらは「そんな名前の変数や関数はどこにも宣言されていない」という意味です。単純なスペルミスのほか、変数のスコープ(有効範囲)を勘違いしているときによく出ます。関数の中で const や let で宣言した変数は、その関数の外からは見えません。
地味に多いのが、ライブラリの読み込み忘れ・順序ミスです。jQueryを読み込む前に $ を使うと、$ is not defined が出ます。ライブラリ本体の script タグを、それを使う自分のコードより先に書く。これでたいてい直ります。
関連記事:jQueryの基本的な使い方|WordPressでの注意点を初心者向けに解説
SyntaxError(構文エラー)
カッコの閉じ忘れ、クォートの不一致、カンマやセミコロンの位置ミスなど、JavaScriptの文法そのものが壊れていると SyntaxError が出ます。やっかいなのは、エラーとして表示される行番号が、実際の原因より少し後ろになりがちなこと。閉じカッコが足りないと、ブラウザは続きを読み進めてしまい、文末まで来てようやく「おかしい」と気づくためです。
このタイプは、エディタの自動整形やカッコの対応ハイライトに頼るのが一番です。私はVS Codeでカッコの色分けを使っていますが、これだけで構文エラーの大半は書いた瞬間に気づけます。エラー行の少し手前から読み返す、という癖もつけておくと安心です。
非同期・Promiseまわりのエラー
fetch やAPI通信などの非同期処理では、エラーの出方が少し変わります。コンソールに Uncaught (in promise) と表示されたら、Promiseの中で起きたエラーが、どこにも受け止められず放置されている合図です。
async/await を使う場合は、try/catch で囲んでエラーを捕まえるのが基本の形になります。
async function getData() {
try {
const res = await fetch("/api/data");
if (!res.ok) throw new Error("HTTP " + res.status);
const data = await res.json();
console.log(data);
} catch (err) {
console.error("取得失敗:", err);
}
}
ここで注意したいのが、fetch は404や500のようなサーバーエラーでは例外を投げない、という仕様です。通信自体が成立すれば fetch は成功扱いになるので、res.ok を自分でチェックしてエラー判定を補う必要があります。
CORSエラー(別ドメインへの通信がブロックされる)
外部APIや別ドメインのデータを fetch したとき、コンソールに「Cross-Origin Request Blocked」や「has been blocked by CORS policy」と出ることがあります。これはブラウザの同一オリジンポリシーによる安全装置で、JavaScript側のバグではありません。
原因は、アクセス先のサーバーが Access-Control-Allow-Origin というレスポンスヘッダーを返していない(または許可するオリジンが合っていない)こと。解決は基本的にサーバー側の設定でしか行えません。自分が管理するサーバーなら適切なヘッダーを追加し、他社のAPIで自由に設定できない場合は、自分のサーバーを経由(プロキシ)させて取りに行く方法が定番です。コンソールでCORSと出たら「これはフロントだけでは直せない種類のエラーだ」と切り分けられるだけで、無駄な試行錯誤を防げます。
出典:TypeError: “x” is (not) “y” – MDN Web Docs / CORS エラー – MDN Web Docs
関連記事:HTTPS通信下でJavaScriptが動かない原因と解決方法
エラーを未然に防ぐ書き方とデバッグの心構え
エラーは出てから直すものですが、出にくくする書き方もあります。日々の小さな習慣が、デバッグにかける時間をぐっと減らしてくれます。
try/catchで「落ちる」のを防ぐ
失敗する可能性のある処理は、try/catch で囲んでおくと、エラーが起きてもページ全体が止まらず、原因のメッセージを自分で出力できます。「どこで何が失敗したか」を catch の中で console.error に残しておくと、後からの調査が劇的に楽になります。何でもかんでも囲むのはやりすぎですが、通信・JSON解析・外部入力の扱いなど、失敗が読めない箇所では積極的に使う価値があります。
エラーメッセージは「翻訳」して読む
初心者ほど、赤い文字を見た瞬間に思考が止まりがちです。でもエラー文は、構造を知れば日本語のように読めます。TypeError(型の間違い)なのか ReferenceError(存在しないものを参照)なのか、まずエラーの種類を見る。次にコロンの後ろの説明文を読む。最後にファイル名と行番号で場所を特定する。この3ステップで、ほとんどのエラーは「何を直せばいいか」まで見えてきます。
困ったときの切り分け手順
それでも原因が見えないときは、範囲を狭めていきます。怪しい処理の前後に console.log を置いて、どこまで動いているかを確認する。スクリプトの一部をコメントアウトして、エラーが消えるかを試す。読み込み順を疑うなら、defer の有無やライブラリの順番を入れ替えてみる。大きな問題を、小さく分けて潰していくのが、遠回りに見えていちばん確実な近道です。
出典:ReferenceError: “x” is not defined – MDN Web Docs / TypeError: “x” is not a function – MDN Web Docs
まとめ
かつてIE専用のエラー対応に費やしていた労力は、IEのサポート終了とともに役目を終えました。いまJavaScriptのエラーと向き合うときの主役は、すべてのモダンブラウザに入っているDevTools(開発者ツール)です。動かないと思ったら、まず F12 でコンソールを開く。これが何より先にやるべき一歩です。
この記事で見てきたエラーは、どれも現場で繰り返し出会う定番ばかりでした。Cannot read properties of null は要素が取れていないか読み込み順のズレ、is not a function はメソッド名や型の取り違え、is not defined は宣言漏れやライブラリの順番、SyntaxError は文法の崩れ、Promiseのエラーは try/catch での受け止め、そしてCORSはサーバー側の設定。原因のパターンが頭に入っていれば、赤いエラーを見ても落ち着いて切り分けられます。
未然に防ぐ工夫も合わせて押さえておきたいところです。失敗しうる処理は try/catch で囲んでメッセージを残し、エディタのカッコ補助で構文ミスをその場で潰す。こうした小さな習慣の積み重ねが、後々のデバッグ時間を大きく削ってくれます。
私自身、長年やってきても新しいエラーには毎回出くわします。それでも怖くないのは、「エラーメッセージは敵ではなく、原因を教えてくれる味方だ」と知っているからです。種類を見て、説明文を読んで、場所を特定する。この読み方さえ身につけば、あなたのデバッグの速さは確実に変わります。次にスクリプトが動かなくなったら、ためらわずコンソールを開いて、エラー文をじっくり読んでみてください。それが解決への最短ルートです。