「動かない…なんで?」を自分で解決するための基本とツールの使い方
JavaScriptを書いていると、ほぼ100%の確率で「思ったとおりに動かない…」という瞬間がきます。
それはあなただけじゃなくて、現場のエンジニア全員そうです。
むしろ「どう壊れているかを調べて直す力(=デバッグ力)」こそが実務でめちゃくちゃ重要になってきます。
この章では次のことをまとめて学びます。
- どんな種類のエラーがあるのか
- エラーをどんな流れで探していけばいいのか
- ブラウザの開発者ツール(デベロッパーツール)をどう使えばいいのか
- 実際にコードを止めて、値をのぞき見する方法(ブレークポイント / debugger)
「バグを直すのが怖い → バグが来ても落ち着いて原因を切り分けられる」に変えていきましょう。
目次
デバッグって何をすること?
デバッグとは、ざっくりいうと
- おかしな挙動(バグ・エラー)を見つけて
- なんでそうなってるか原因を突き止めて
- 直す
という一連の作業のことです。
「デバッグできるようになる=詰まったときに自力で前に進めるようになる」なので、これは本当に強いです。
エラーには大きく2種類ある
JavaScriptでは、エラーといっても全部同じではありません。よく出てくるのは次の2タイプです。
1. 文法エラー(構文エラー)
- 書き方そのものが間違っていて、そもそも実行できない状態。
- たとえばカッコが閉じていないとか、
constのつもりがcnotsとタイプミスしたとか。 - ブラウザのコンソールに
SyntaxError: ...のようなエラーメッセージが出ます。 - どこで壊れてるかをブラウザが教えてくれるので、比較的直しやすいです。
イメージ:
function hello( {
console.log("Hi!");
}
// ↑ カッコが合ってないので構文エラー
2. ロジックエラー(実行時の間違い)
- コード自体は動く。でも「期待した結果になってない」パターン。
- たとえば計算がずれている、想定外の値が入っている、if の分岐が間違ってる、など。
- 実行はできるのでブラウザは「壊れてますよ」とは教えてくれないこともあります。
- これがいちばん時間がかかるし、心を削ってくるところです。
イメージ:
function add(a, b) {
return a - b; // 本当は足し算したいのに引き算してる
}
console.log(add(5, 3)); // 期待は8なのに2になる
この「ロジックエラー」をつぶすときに本気で役に立つのが、ブラウザに内蔵されている デベロッパーツール(開発者ツール) なんです。
デベロッパーツールとは?
Chrome や Edge などのブラウザには、開発者向けのツールセットが最初から入っています。
これが「デベロッパーツール(開発者ツール / DevTools)」と呼ばれるものです。
開き方の例(Chrome / Edge 共通):
- Windows:
F12キー、または右クリック →「検証」 - Mac:
⌥Option + ⌘Command + I(もしくは右クリック →「検証」)
このツールでできることの一部:
- コンソール(Console)で値を出力・確認する
- 実際に動いているJavaScriptを途中で止めて、中身をのぞく
- 1行ずつ実行して「どこでおかしくなったか」を追跡する
- その瞬間の変数の中身を見る
つまり「なんで壊れてるか」を調べるためのレントゲンです。
デバッグの第一歩:console.log()とalert()
エラーの原因を調べたいとき、まず多くの人がやるのが「値を出して確認する」です。
console.log(…)
const price = 1200;
console.log("priceの中身:", price);
こうすると、デベロッパーツールの Console(コンソール)タブ に値が表示されます。
「このタイミングでこの値が入ってるんだな」を見るのに便利。
alert(…)
alert("ここまで処理きたよ!");
これは画面上にポップアップを出す方法です。
DevToolsを開いていなくても確認できるので、超シンプルな確認には便利。
ただし何回も出るとストレスなので乱用はしない感じです。
でも…
ログをガンガン仕込んでいくやり方は、数行ならいいんですが、処理が長くなると逆に追いにくくなりますよね。
もっとスマートに「途中で止めて中身を見る」ことができたら最高です。
それが次の「debugger」と「ブレークポイント」です。
コードを途中で止める:debugger; を入れる
debugger; という1行を書くと、その行でプログラムの実行がピタッと止まります。(デベロッパーツールを開いた状態で有効)
止まった時点で、変数の中身や処理の流れをじっくり観察することができます。
サンプルHTML(入力フォーム+JS)
<!DOCTYPE html>
<html>
<head>
<title>フォーム入力のハイライト</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="panel">
<form>
<div class="form-field">
<label for="user_name">ユーザー名:</label>
<input type="text" id="user_name">
</div>
<div class="form-field">
<label for="password">パスワード:</label>
<input type="password" id="password">
</div>
<div class="form-field">
<label for="pref">都道府県:</label>
<select id="pref">
<option value="1">北海道</option>
<option value="2">青森県</option>
<option value="3">岩手県</option>
<option value="4">秋田県</option>
<option value="5">宮城県</option>
<option value="6">福島県</option>
</select>
</div>
<div class="form-field">
<label for="comment">その他(自由記入)</label>
<textarea id="comment" rows="5" cols="50"></textarea>
</div>
</form>
</div>
<script src="./focus_debug_sample.js"></script>
</body>
</html>
サンプルJS(debugger; で止める)
// フォーカスが当たったときの処理
function handleFocus(evt) {
debugger; // ←ここで実行が一時停止する
// いったん全部のclassをリセット
for (const el of fields) {
el.removeAttribute("class");
}
// 今フォーカスが当たった要素だけclassを付ける
evt.target.setAttribute("class", "is-active");
}
// 入力系の要素をまとめて取得(input, select, textarea)
const fields = document.querySelectorAll("input, select, textarea");
// 全部に「フォーカスされたら handleFocus を呼ぶ」よう登録
for (const item of fields) {
item.addEventListener("focus", handleFocus);
}
実際にやる手順はこうなります
- ブラウザでこのページを開く
- デベロッパーツール(開発者ツール)を開く
- フォームのどこかをクリックしてフォーカスする
debugger;の行で実行が止まる
止まっている間は、DevToolsのConsoleタブで fields や evt.target などの変数名を入力すると、その瞬間の中身を確認できます。
つまり、
- どの要素が拾えてる?
- ちゃんとclass外れてる?
- どの要素に
is-active付こうとしてる?
をリアルタイムで覗ける、ってことです。
ブレークポイントでコードを止める(手動でストップ位置を指定する)
debugger; を書き込まなくても、ブラウザ側で「この行で止めて」と指定することもできます。
これがブレークポイントです。
ブレークポイントを使うと、
- 好きな行で実行を一時停止できる
- 止めた時点での変数の値をチェックできる
- そこから1行ずつ動かせる(ステップ実行)
- 関数の呼び出し経路(どこから呼ばれたか)まで見れる
という、かなり本格的なデバッグができます。
ブレークポイントの練習用サンプル
これは簡単な「四則演算フォーム」です。演算子(+、-、×、÷)と2つの数字を入力すると結果を表示します。
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>四則演算デバッグ練習</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<form>
<h2>四則演算テスター</h2>
<input type="number" id="val1" />
<select id="op">
<option value="add">+</option>
<option value="sub">-</option>
<option value="mul">×</option>
<option value="div">÷</option>
</select>
<input type="number" id="val2" />
=
<span id="answer"></span>
</form>
<script src="./calc_debug_sample.js"></script>
</body>
</html>
CSS(見やすさ用)
* {
font-size: 24px;
}
body {
display: flex;
justify-content: center;
align-items: center;
background: #eeeeee;
margin: 0;
overflow: hidden;
}
form {
margin-top: 20px;
zoom: 2;
text-align: center;
}
input[type="number"] {
width: 30px;
}
#answer {
width: 30px;
display: inline-block;
}
JavaScript
// 入力が変わったら計算しなおす関数
function refreshResult() {
// 計算結果を作る
const out = doMath(
Number(firstNum.value), // 1つ目の数字
Number(secondNum.value), // 2つ目の数字
operatorSelect.value // 選択中の演算子
);
// 計算結果を画面に表示
outputArea.innerHTML = out;
}
// 計算の中身
function doMath(a, b, kind) {
let result;
switch (kind) {
case "add":
result = plus(a, b);
break;
case "sub":
result = minus(a, b);
break;
case "mul":
result = times(a, b);
break;
case "div":
result = divide(a, b);
break;
}
return result;
}
// 足し算
function plus(a, b) {
return a + b;
}
// 引き算
function minus(a, b) {
return a - b;
}
// 掛け算
function times(a, b) {
return a * b;
}
// 割り算
function divide(a, b) {
return a / b;
}
// それぞれの要素を取得
const operatorSelect = document.getElementById("op");
const firstNum = document.getElementById("val1");
const secondNum = document.getElementById("val2");
const outputArea = document.getElementById("answer");
// 入力や選択が変わったときに計算し直すようイベント登録
operatorSelect.addEventListener("change", refreshResult);
firstNum.addEventListener("change", refreshResult);
secondNum.addEventListener("change", refreshResult);
ブレークポイントの置き方(Chrome / Edge)
- デベロッパーツールを開く
- 上部のタブから Sources をクリック
- 左側にあるファイル一覧(Pageなどと表示されているツリー)から
calc_debug_sample.jsを選ぶ - 右側にソースコードが表示されるので、止めたい行番号をクリックする
すると、その行に青いマーク(または矢印・●の印)がつきます。
これがブレークポイントです。
たとえば switch (kind) { ... } の行あたりにブレークポイントを置いておくと、どの演算が選ばれたのか、a と b に何が入っているのかをその瞬間でチェックできます。
止まっているときに何ができるの?
ブレークポイントで実行が止まった状態になると、デベロッパーツールの右側パネルなどでこんなことができます。
1. 変数の中身を確認する
- ソースコード上でマウスカーソルを変数名に乗せると、その時点の値がポップアップで表示されます。
- Consoleタブで変数名を直接入力しても、その値が見られます。
「いま firstNum.value はちゃんと数字になってる?」
「kind は ‘add’ のはずだけど違う値入ってない?」
といった確認が一発でできます。
2. Scope(スコープ)を見る
DevToolsには「Scope」みたいな領域があり、今実行中の関数内で使える変数(ローカル変数など)が一覧で見られます。
複雑なオブジェクトの中身も展開して追えるので、フォームの値や処理途中の一時変数を丁寧に見たいときに便利です。
3. Call Stack(コールスタック)を見る
「この関数ってどこから呼ばれたんだっけ?」という呼び出し履歴も見られます。
とくにプロジェクトが大きくなると、「誰がこの関数叩いてるの?」が分からなくなるので、ここはかなり役立ちます。
一時停止した後の操作(ステップ実行)
止まったあとの画面には、再生ボタンや矢印アイコンが並びます。
これらで“どんな進め方をするか”をコントロールできます。
よく使うものだけ押さえておきましょう:
- ▶(再開 / Resume)
- 今止まってるところからプログラムを再開します。
- 次のブレークポイントがあれば、そこでまた止まります。
- ⤵ Step Over(ステップオーバー)
- 今の行を実行して、次の行でまた止まります。
- その行が関数呼び出しだったとしても、中身の中には入らず、ひとまとめで「呼んだことにして」進んでくれるイメージです。
- 「ざっくり流れを追いたいとき」に便利。
- ⤴ Step Into(ステップイン)
- 関数呼び出しの行だった場合、その関数の中に潜って、1行ずつ見に行きます。
- 「この関数の中でバグってそうなんだよな…」というときに使います。
- かなり細かく追いかけたいとき向け。
- ↩ Step Out(ステップアウト)
- 今入っている関数の残りを一気に実行し、呼び出し元に戻ります。
- 深いところに潜りすぎたからとりあえず抜けたい、というときに便利。
この「1行ずつ確かめる」っていう感覚は、はじめて触ると地味に感動します。
何がいつ実行されるのか、頭の中じゃなくて実際の流れで理解できるようになるからです。
まとめ(ここを押さえておくと安心)
- バグは必ず出ます。むしろ「バグの探し方」を知ってる人が強いです。
- エラーには「文法エラー(すぐ気づける系)」と「ロジックエラー(動くけどおかしい系)」がある。
console.log()やalert()は、どこまで動いてるか・何が入っているかを手早く確認するための基本の道具。- もっと丁寧に調べたいときは、開発者ツールを開いて、
debugger;で好きな場所で停止させる- ブレークポイントで任意の行に停止ポイントを置く
- 変数の中身をリアルタイムで見る
- ステップ実行で1行ずつ動きを追いかける
- これができるようになると「なんか動かないから一旦やり直そう…」ではなく、「どこからおかしいのか順番に見よう」に変わります。これは本当に大きな差になります。
いま「正直ちょっとむずかしそうかも」と感じたとしても大丈夫です。
このあとのフェーズ(フォーム処理・API通信・DOM操作・イベント処理など)に進むと、デバッグは必ず必要になります。
そこで少しずつ触っていけば手になじんでいきます。
焦らなくて大丈夫です。



