JavaScriptのエラーの読み方|3種類の直し方と5つの手順。提出コード24本で分かった「エラーが出ないミス」の見つけ方
執筆・監修: 徐 聖博/株式会社シンシア 代表取締役社長
JavaScriptのエラーは「種類・メッセージ・行番号」の3つで読みます。ReferenceError・TypeError(null)・SyntaxErrorをわざと壊したコードで再現して直し方を確認。ナミノリの修了課題24本を動かし直すと、見落とされていたのはエラーを出さずに間違えるコードでした。その見つけ方も解説します。
目次
JavaScriptのエラーの読み方|赤い文字より怖いのは、何も出ないミス
JavaScriptが動かないとき、最初にやることは決まっています。Consoleを開いて、赤いエラーの種類・メッセージ・行番号を読むことです。初心者が出会うエラーはほとんどが3種類で、種類が分かれば疑う場所はかなり絞れます。
ただ、この記事で一番伝えたいのはその先です。
ナミノリの講座で提出されたコードを、あとから全部動かし直してみました。エラーで止まるコードは、提出した本人にもすぐ分かります。見落とされていたのは、エラーを1つも出さずに、間違った答えを返すコードのほうでした。
この記事では、エラーを読む5つの手順と3種類のエラーの直し方を、わざと壊したコードで確かめます。そのあとで、エラーが出ないミスの見つけ方を扱います。
提出コード24本を動かし直して分かったこと
ナミノリの「Ruby初級講座」の修了課題には、条件に合う数のリストを返す関数や、点数から成績を返す関数を自分で書いて提出する問題が3問あります。2024年9月〜2025年1月に5人が提出した24本(再提出を含む)を、問題文の例と、例以外の値で実行しました。
| 結果 | 本数 | 中身 |
|---|---|---|
| エラーで止まった | 5本 | 構文エラー4本、名前が見つからないエラー1本 |
| エラーは出ないが、答えが間違っていた | 6本 | 6本中5本は、問題文の最初の例では正しい答えを返した |
| 動くが、問題の指示(関数にする)と違う形 | 3本 | 入力を受け取って表示するだけ |
| 正しく動いた | 10本 |
エラーで止まった5本は、すべて0点でした。止まれば誰でも気づけます。
厄介なのは真ん中の6本です。たとえば「num以下の3の倍数を返す」問題で、num を使わずに 10 と書いてあるコードがありました。問題文の例は num = 10 なので、例を試す限り正しい答えが出ます。ほかにも、「100以下」の100を範囲外にしてしまうもの、「3の倍数または3を含む数」の後半の条件が抜けているものがありました。
この6本のうち2本は、人が読んで採点したときも満点になっていました。 エラーが出ないミスは、書いた本人だけでなく、読む人の目もすり抜けます。
※ 言語はRubyですが、エラーの分かれ方(構文エラー/名前が見つからない/値に対してできない操作)はJavaScriptと同じです。この記事の例はすべてJavaScriptに置き換えています。母数は5人・24本と小さく、社内の確認用アカウントの提出は除きました。集計は2026年9月27日。
エラーを読む5つの手順
- 再現する操作を決める。「ページを開いた直後」「ボタンを押したとき」など、毎回同じ操作で起きるかを確かめる
- Consoleを開き、いったんクリアしてから再現する。古いエラーと混ざらないようにするため。クリアは修正ではない
- 最初の赤いエラーを読む。エラーが連鎖しているときは、最初の1つが原因のことが多い。読むのは「種類」「メッセージ」「右端のファイル名と行番号」の3つ
- 疑う場所を1か所だけ直す。複数を同時に変えると、どれが効いたか分からなくなる
- 同じ操作でもう一度試す。直ったか、元々動いていた部分を壊していないかを見る
Consoleは、Chromeならページ上で右クリック→「検証」→「Console」タブで開けます。Windowsは Ctrl + Shift + J、Macは Command + Option + J でも開きます。
3種類のエラーと直し方
以下のコードは、どれもわざと間違えた例です。1つずつ、新しいHTMLファイルに貼って試してください。エラーの文言は2026年9月にChromeで表示を確認したものです。ほかのブラウザでは言い回しが変わります。
ReferenceError:その名前が見つからない
<script>
const price = 1200;
const taxRate = 0.1;
console.log(prise * (1 + taxRate));
</script>
Consoleにはこう出ます。
Uncaught ReferenceError: prise is not defined
読み方:prise という名前が定義されていない、という意味です。定義したのは price なので、つづりの違いです。
直し方:使っている名前を、定義した名前にそろえます。console.log(price * (1 + taxRate)); で 1320 と表示されれば直っています。
ReferenceErrorが出たら、まず定義した名前と使った名前を並べて見比べてください。大文字と小文字(Price と price)も別の名前として扱われます。提出コードの1本も、どこにも定義していない名前を使って止まっていました。
TypeError:その値には、その操作ができない
JavaScript入門で作ったカウンターを、1か所だけ壊した例です。
<p>今日の回数:<span id="count">0</span></p>
<button id="add">1回増やす</button>
<script>
const countElement = document.querySelector("#count");
const addButton = document.querySelector("#add-button");
let count = 0;
addButton.addEventListener("click", () => {
count += 1;
countElement.textContent = String(count);
});
</script>
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
読み方:null に対して addEventListener を読もうとした、という意味です。null は「何もない」を表す値です。つまり addButton の中身が空で、ボタンが見つかっていません。
直し方:HTMLのボタンは id="add" なのに、JavaScriptでは #add-button を探しています。document.querySelector("#add") に直します。
エラーが出た行(addEventListener の行)ではなく、その1行上で値を取り出したところが原因です。迷ったら、エラーの行の直前に console.log(addButton); を入れて、実際の中身を表示してみてください。null と出れば、探し方が間違っています。
if (addButton) { ... } で囲んでエラーを消す方法もありますが、ボタンが必要なページでそれをやると、エラーが消えるだけで、ボタンは動かないままです。直すべきはつづりのほうです。
SyntaxError:構文として読めない
<script>
console.log("学習開始);
</script>
Uncaught SyntaxError: Invalid or unexpected token
読み方:文字列を閉じる " がないため、どこまでが文字列か分からなくなっています。
直し方:console.log("学習開始"); と閉じます。
構文エラーには、ほかのエラーと違う点が2つあります。
- そのscriptは1行も実行されない。ReferenceErrorやTypeErrorは、エラーの行より前は実行されます。構文エラーは、実行する前の「読む」段階で止まります
- 行番号が、原因の場所とずれることがある
2つ目は、括弧の閉じ忘れで起きます。
<script>
function judge(score) {
if (score >= 80) {
return "合格";
}
return "不合格";
console.log(judge(85));
</script>
Uncaught SyntaxError: Unexpected end of input
「入力が途中で終わった」という意味です。行番号は、最後の行を指します。ところが原因は、return "不合格"; の次の行で } を閉じ忘れたことです。Unexpected end of input が出たら、閉じ忘れを上にさかのぼって探してください。提出コードで構文エラーになった4本は、end(JavaScriptの } にあたる)の閉じ忘れが1本、|| のあとに何も書いていない式が2本、Rubyにない書き方が1本でした。
エラーが出ないのに、答えが間違っているとき
ここからが本題です。提出コードで見落とされていた型を、JavaScriptで再現します。どれもConsoleには何も出ません。
型1:例の数字を、そのまま書いてしまう
function multiplesOfThree(num) {
const result = [];
for (let i = 1; i <= 10; i++) {
if (i % 3 === 0) {
result.push(i);
}
}
return result;
}
console.log(multiplesOfThree(10));
console.log(multiplesOfThree(20));
[3, 6, 9]
[3, 6, 9]
(Chromeでは先頭に要素の数が付いて (3) [3, 6, 9] のように表示されます)
1行目は正しい答えです。2行目は、本当は [3, 6, 9, 12, 15, 18] になるはずです。i <= 10 が i <= num になっていません。問題文の例(10)だけで試すと、正しく見えます。
型2:境界の数を、範囲の外にしてしまう
function checkRange(num) {
if (num > 0 && num < 100) {
return "OK";
}
return "範囲外です";
}
console.log(checkRange(50));
console.log(checkRange(100));
OK
範囲外です
「100以下」なら、100はOKのはずです。< と <= の1文字の違いです。50のような真ん中の数で試しても見つかりません。 境界の考え方はif文の記事で詳しく扱っています。
型3:条件の片方が抜けている
function threeRelated(num) {
const result = [];
for (let i = 1; i <= num; i++) {
if (i % 3 === 0) {
result.push(i);
}
}
return result;
}
console.log(threeRelated(31));
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
問題は「3の倍数または3を含む数」でした。13・23・31が入っていません。i % 3 === 0 || String(i).includes("3") にすると [3, 6, 9, 12, 13, 15, 18, 21, 23, 24, 27, 30, 31] になります。num = 10 なら、どちらの書き方でも答えは同じ [3, 6, 9] です。
もう1つ、よくあるものを挙げておきます。"5" + 3 はエラーにならず、"53" という文字列になります。数値の計算のつもりでも、片方が文字列だとつながってしまいます(変数とデータ型の記事で扱っています)。
見つけ方:試す値を3種類そろえる
エラーが出ないミスは、試す値を増やすことでしか見つかりません。書き終えたら、最低でも次の3種類を試してください。
| 試す値 | 例(num以下の3の倍数、numは1〜100) | 見つかるミス |
|---|---|---|
| 問題文の例 | 10 | 大きな勘違い |
| 例と違う値 | 20、31 | 型1(例の数字を書き込む)、型3(条件の抜け) |
| 境界とその外 | 1、100、0、101 | 型2(< と <=) |
先に「この値なら、この答えになるはず」を紙に書いてから実行するのがコツです。実行してから答えを見ると、出てきた答えが正しく見えてしまいます。
人やAIに質問するときのテンプレート
自分で解決できないときは、次の形で質問すると、相手が聞き返さずに調べ始められます。
やりたいこと:ボタンを押したら数字を1増やしたい
操作:index.html をChromeで開き、「1回増やす」を押した
期待した結果:0が1になる
実際の結果:何も変わらない。Consoleに
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
(index.html の12行目)
コード:問題が起きる部分だけ(ここに貼る)
試したこと:id のつづりを見直したが、同じエラーが出る
環境:Chrome(Mac)
エラーの文は、要約せずにそのままコピーしてください。画面のスクリーンショットやログには、メールアドレスや管理画面のURLが写り込むことがあります。貼る前に見直してください。
AIに聞くときも同じです。ただし、AIが出した修正はそのまま貼らずに、どこが変わったかを1行ずつ確かめてから使ってください。エラーを消すだけの修正(先ほどの if (addButton) のようなもの)が返ってくることもあります。
よくある質問
エラーが英語で読めません
全文を訳す必要はありません。見るのは、先頭のエラーの種類(ReferenceError など)、is not defined や null のような目立つ単語、右端の行番号の3つです。文をそのまま検索すると、同じエラーで困った人の解決策が見つかることも多いです。
赤いエラーが何も出ていないのに、ボタンが動きません
まず、保存してから再読み込みしたかを確かめてください。それでも動かないなら、この記事の「エラーが出ないのに、答えが間違っているとき」に当てはまる可能性があります。途中に console.log() を入れて、値が思ったとおりかを1か所ずつ確かめます。サーバーへの送信を伴う処理なら、Networkパネルで通信が起きているかを見る方法もあります(Chrome DevTools入門講座の6回目で扱っています)。
黄色いメッセージも直すべきですか?
黄色は警告で、動作はしています。赤いエラーを先に直してください。広告ブロックなどのブラウザ拡張機能が出すメッセージが混ざることもあるので、気になるときはシークレットウィンドウで試すと切り分けられます。
行番号の場所を見ても、間違いが見つかりません
構文エラーなら、原因はその行より上にあることがあります(Unexpected end of input は特にそうです)。TypeErrorなら、エラーの行で使っている値を取り出した行を疑ってください。
まとめ
- エラーを読むときは、種類・メッセージ・行番号の3つを見る
- ReferenceErrorは名前のつづり、TypeError(
null)は要素が見つかっていない、SyntaxErrorは閉じ忘れを最初に疑う - 構文エラーはscript全体が動かない。行番号が原因とずれることがある
- 提出コード24本では、エラーで止まった5本より、エラーを出さずに間違えた6本のほうが見落とされていた(2本は採点でも満点)
- 書き終えたら、例・例と違う値・境界の3種類で試す
エラーの読み方と学び方の全体像は、プログラミング入門講座の5回目「エラーと学習の進め方」で扱っています(全5回・無料)。Consoleの使い方を画面つきで確かめたい人は、Chrome DevTools入門講座の5回目「Consoleパネル ― エラーメッセージを読む」から始めてください。
手を動かして確かめるなら、JavaScript練習問題10問を「例と違う値」でも試してみてください。
参考資料
- MDN「JavaScript エラーリファレンス」 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors
- MDN「何が間違っている? JavaScript のトラブルシューティング」 https://developer.mozilla.org/ja/docs/Learn_web_development/Core/Scripting/What_went_wrong
- MDN「ReferenceError」 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
- MDN「TypeError」 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypeError
- Chrome DevTools「Console の概要」 https://developer.chrome.com/docs/devtools/console?hl=ja
無料の学習講座で、いまから手を動かす
AI開発からWeb開発まで、未経験でも進められる講座を無料で公開しています。
会員登録(無料) すると、気になる求人の保存と講座の受講履歴の記録ができます。
この順番で合っているか、確認しませんか
学習の順番は、目指す職種によって変わります。いま考えている進め方を書いて送ってもらえれば、無料講座の内容と実際の求人要件に照らして返答します。
相談を書いて送る(無料・会員登録なし)返答までお時間をいただくことがあります。