読み込み中...

var_dump()に代わるJavaScriptのデバッグ方法10選

JavaScriptのvar_dump()の代わりとなるデバッグ方法 JS
この記事は約17分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●JavaScriptにvar_dump()がない理由

みなさんは、PHPのデバッグでよく使われるvar_dump()関数をご存知でしょうか。

この関数は、変数の値や型を出力するのにとても便利ですよね。

ところが、JavaScriptにはvar_dump()に相当する組み込みの関数がありません。

それはなぜでしょうか。その理由を探るために、まずはPHPのvar_dump()の役割を確認してみましょう。

○PHPのvar_dump()の役割

PHPのvar_dump()は、変数の値と型を出力するデバッグ用の関数です。

配列やオブジェクトの中身を確認したい時に、とても重宝します。

例えば、次のようなPHPコードがあるとします。

$name = "Alice";
$age = 24;
$hobbies = ["読書", "旅行", "料理"];

var_dump($name, $age, $hobbies);

このコードを実行すると、次のような出力が得られます。

string(5) "Alice"
int(24)
array(3) {
  [0]=>
  string(6) "読書"
  [1]=>
  string(6) "旅行"
  [2]=>
  string(6) "料理"
}

各変数の値と型が一目瞭然ですね。

こういった出力はデバッグ時に非常に役立ちます。

○JavaScriptの変数の特徴

一方、JavaScriptはPHPとは言語の特性が異なります。

JavaScriptでは、変数の型は動的に決まります。

つまり、同じ変数に文字列を代入したり数値を代入したりできるのです。

let value = "Hello";
console.log(typeof value); // "string"

value = 123;
console.log(typeof value); // "number"

このように、JavaScriptでは変数の型はその時々で変化します。

そのため、PHPのようにvar_dump()で型を出力する必要性が低いのです。

とはいえ、JavaScriptにもデバッグ用の出力機能は不可欠です。

それを担うのが、console.log()をはじめとするconsoleオブジェクトのメソッドです。

次章では、console.log()を使ったデバッグ方法を詳しく見ていきましょう。

●console.log()を使ったデバッグ方法

JavaScriptにはvar_dump()はありませんが、代わりにconsole.log()を使ってデバッグができます。

console.log()は、ブラウザのデベロッパーツールのコンソールにメッセージを出力する関数です。

変数の値を確認したり、コードの実行フローを追跡したりするのに便利です。

では早速、console.log()の使い方を見ていきましょう。

○サンプルコード1:console.log()の基本的な使い方

まずは、console.log()の基本的な使い方から。文字列や数値、真偽値などのプリミティブ型の値を出力してみます。

console.log("Hello, World!");
console.log(123);
console.log(true);

実行結果

Hello, World!
123
true

ご覧の通り、console.log()に渡した値がそのままコンソールに出力されます。

複数の値を同時に出力することもできます。

const name = "Alice";
const age = 20;
console.log("名前:", name, "、年齢:", age);

実行結果

名前: Alice 、年齢: 20

カンマ区切りで値を渡せば、スペース区切りで出力されるのです。

これは、変数の値をまとめて確認する時に役立ちます。

○サンプルコード2:オブジェクトのデバッグ

console.log()は、オブジェクトの中身を確認する時にも大活躍。

次のようなオブジェクトがあるとしましょう。

const person = {
  name: "Bob",
  age: 24,
  hobbies: ["読書", "旅行", "料理"]
};

console.log(person);

実行結果

{name: "Bob", age: 24, hobbies: Array(3)}

オブジェクトをそのままconsole.log()に渡すと、オブジェクトのプロパティ名と値のペアが出力されます。

ただし、hobbiesのようなオブジェクトの中のオブジェクト(配列など)は、デフォルトでは中身まで展開されません。

そこで、こんな風にJSON.stringify()を使ってオブジェクトを文字列化すると、より詳細な情報が得られます。

console.log(JSON.stringify(person, null, 2));

実行結果

{
  "name": "Bob",
  "age": 24,
  "hobbies": [
    "読書",
    "旅行",
    "料理"
  ]
}

JSON.stringify()の第2引数にnull、第3引数に2を指定することで、オブジェクトが整形されて出力されるのです。

○サンプルコード3:console.table()でテーブル表示

オブジェクトの配列をデバッグする時は、console.table()が便利です。

これを使えば、データをテーブル形式で見やすく出力できます。

const users = [
  {id: 1, name: "Alice", age: 20},
  {id: 2, name: "Bob", age: 24},
  {id: 3, name: "Carol", age: 22}
];

console.table(users);

実行結果

┌─────────┬────┬───────┬─────┐
│ (index) │ id │ name  │ age │
├─────────┼────┼───────┼─────┤
│    0    │ 1  │ Alice │ 20  │
│    1    │ 2  │ Bob   │ 24  │
│    2    │ 3  │ Carol │ 22  │
└─────────┴────┴───────┴─────┘

各オブジェクトのプロパティがカラムに、オブジェクト自体がローになって表示されます。

データの構造が一目瞭然ですね。

console.log()とconsole.table()を使い分ければ、さまざまな値を見やすく出力できるでしょう。

でも、これだけでは物足りないと感じた方もいるかもしれません。

もっと本格的なデバッグがしたい!という方におすすめなのが、ブラウザの開発者ツールです。

●ブラウザの開発者ツールを活用する

console.log()はシンプルで使いやすいデバッグ方法でしたが、もっと高度なデバッグがしたいという方も多いでしょう。

そんな時は、ブラウザの開発者ツールを活用するのがおすすめです。

開発者ツールを使えば、JavaScriptのコードをステップ実行したり、変数の値を監視したりできます。

バグの原因を突き止めるのにとても役立つんですよ。

それでは、ChromeとFirefoxを例に、開発者ツールの使い方を見ていきましょう。

○サンプルコード4:Sources パネルでブレークポイントを設定

JavaScriptのコードを1行ずつ実行したい時は、ブレークポイントを設定するのが便利です。

まず、開発者ツールのSources パネルを開きます。

そして、コードの任意の行の左側をクリックすると、その行にブレークポイントが設定されます。

function sayHello(name) {
  debugger;  // ブレークポイントを設定
  const message = `Hello, ${name}!`;
  console.log(message);
}

sayHello("Alice");

上記のコードを実行すると、debugger文の行で実行が一時停止します。

そこから、ステップ実行ボタンを使ってコードを1行ずつ進められるのです。

変数の値がどう変化するのか、関数がどう呼び出されるのかを確認しながらデバッグできるので、とても便利です。

○サンプルコード5:Console パネルで式を評価

開発者ツールのConsole パネルでは、その場で任意のJavaScriptコードを実行できます。

これを使えば、変数の値を確認したり、関数を呼び出したりできるんです。

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log(doubled);

上記のコードを実行した後、Console パネルで次のように入力すると、doubledの値が表示されます。

> doubled
(5) [2, 4, 6, 8, 10]

また、Console パネルで関数を呼び出すこともできます。

> sayHello("Bob")
Hello, Bob!
undefined

sayHello関数を呼び出すと、コンソールにメッセージが出力されますね。

Console パネルは、その場でコードを試したい時にとても重宝します。

○サンプルコード6:Network パネルでAPIリクエストをチェック

JavaScriptからサーバーにデータを送信する際、意図したデータが正しく送れているか確認したいことがあります。

そんな時は、開発者ツールのNetwork パネルが役に立ちます。

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({key: 'value'})
});

上記のコードを実行すると、Network パネルにPOSTリクエストが表示されます。

リクエストの詳細を確認することで、送信したデータが正しいかチェックできるのです。

また、サーバーからのレスポンスの内容もNetwork パネルで確認できます。

APIからのデータ取得がうまくいっているか、ステータスコードは何か、といったことが一目でわかります。

●Node.js環境でのデバッグ

ここまで、ブラウザ上でのJavaScriptデバッグ方法を見てきましたが、Node.js環境でのデバッグ方法も押さえておきたいところです。

Node.jsを使ったサーバーサイドのJavaScript開発が盛んな昨今、Node.jsでのデバッグスキルは必須と言えるでしょう。

それでは、Node.jsならではのデバッグテクニックを2つ紹介しましょう。

○サンプルコード7:Node.jsのinspectモードを使う

Node.jsには、inspectモードというデバッグ専用のモードが用意されています。

これを使えば、コードにブレークポイントを設定して、対話的にデバッグができます。

まず、次のようなJavaScriptファイル(app.js)を用意します。

function sum(a, b) {
  const result = a + b;
  return result;
}

const total = sum(5, 3);
console.log(total);

そして、ターミナルから次のコマンドを実行します。

node inspect app.js

すると、inspectモードが起動し、最初の行で停止します。

< Debugger listening on ws://127.0.0.1:9229/...
< For help, see: https://nodejs.org/en/docs/inspector
<
Break on start in app.js:1
> 1 function sum(a, b) {
  2   const result = a + b;
  3   return result;
debug>

ここで、n(next)コマンドを入力すると、次の行に進みます。

c(continue)コマンドを入力すると、次のブレークポイントまで実行が進みます。

また、replコマンドを入力すると、その時点での変数の値を確認できます。

debug> repl
Press Ctrl + C to leave debug repl
> a
5
> b
3

このように、inspectモードを使えば、Node.jsのコードを対話的にデバッグできるのです。

○サンプルコード8:Visual Studio CodeのDebuggerを利用

IDEのVisual Studio Code(VSCode)には、Node.jsのデバッグ機能が組み込まれています。

これを使えば、GUIでNode.jsのデバッグが行えます。

まず、VSCodeでNode.jsのプロジェクトを開きます。

そして、デバッグしたいファイルを開いた状態で、左側の「Run and Debug」アイコンをクリックします。

次に、「Run and Debug」ビューの上部にある「create a launch.json file」リンクをクリックし、Node.jsの環境を選択します。

すると、.vscode/launch.jsonファイルが生成されます。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "program": "${workspaceFolder}/app.js"
    }
  ]
}

この設定ファイルでは、programフィールドにデバッグ対象のファイル名を指定します。

あとは、コードにブレークポイントを設定し、「Run and Debug」ビューから「Launch Program」を選択して実行するだけです。

VSCodeのDebuggerを使えば、変数の値をホバーで確認したり、ウォッチ式を設定したりと、GUIでの快適なデバッグが可能です。

Node.jsでのデバッグは、ブラウザでのデバッグとはまた違った面白さがあります。

サーバーサイドのロジックを追うのは、頭を使う作業ですが、スキルアップには持ってこいです。

●よくあるエラーと対処法

JavaScriptを書いていると、誰もが一度は遭遇するエラーがいくつかあります。

エラーメッセージを見ただけでは原因がわからず、頭を抱えてしまった経験はないでしょうか。

ここでは、よくあるエラーとその対処法を3つ紹介します。

エラーと上手に付き合えるようになれば、デバッグ効率が格段に上がるはずですよ。

○TypeError: Cannot read property ‘…’ of undefined

このエラーは、undefinedな値のプロパティにアクセスしようとした時に発生します。

例えば、次のようなコードがあるとします。

const user = {
  name: 'Alice',
  age: 20
};

console.log(user.address.city);

このコードでは、userオブジェクトにaddressプロパティが存在しないため、user.addressはundefinedになります。

そのundefinedな値に対して、さらにcityプロパティにアクセスしようとしているために、TypeErrorが発生するのです。

対処法としては、アクセスする前にプロパティの存在チェックを行うことです。

console.log(user.address && user.address.city);

&&演算子を使って、user.addressがtruthyな値(undefinedでない値)の場合だけ、user.address.cityにアクセスするようにします。

こうすれば、エラーを回避できます。

○ReferenceError: ‘…’ is not defined

このエラーは、存在しない変数を参照しようとした時に発生します。

次のようなコードを見てみましょう。

console.log(x);

このコードでは、変数xが定義されていないため、ReferenceErrorが発生します。

対処法としては、変数を使う前に、その変数が確かに定義されているか確認することです。

変数のスコープにも注意が必要ですね。

let x = 10;
console.log(x);

このように、console.logを実行する前に変数xを定義すれば、エラーは発生しません。

○SyntaxError: Unexpected token …

このエラーは、JavaScriptの構文に誤りがある場合に発生します。

例えば、次のようなコードは、関数呼び出しの括弧が閉じられていないため、SyntaxErrorが発生します。

console.log('Hello, world!';

対処法は簡単です。

構文エラーの箇所を見つけて修正するだけですね。

console.log('Hello, world!');

括弧を正しく閉じることで、エラーが解消されます。

エラーメッセージをしっかり読めば、大抵の場合は原因がわかるものです。

エラーを恐れず、むしろ積極的にエラーと向き合っていくことが大切ですよ。

●デバッガーの応用例

さて、ここまでJavaScriptのデバッグ方法について色々と学んできましたが、もう少し踏み込んだテクニックを知りたいと思っている方もいるのではないでしょうか。

そこで、ここではconsoleオブジェクトを使った、ちょっと変わったデバッグ方法を2つ紹介します。

普段のデバッグにも役立つはずですよ。

○サンプルコード9:console.assert()で条件付きログ出力

console.assert()は、第1引数の条件式がfalseの時だけ、第2引数以降の値をコンソールに出力するメソッドです。

これを使えば、特定の条件が満たされた時だけログを出力できるので、デバッグが捗ります。

例えば、次のようなコードがあるとします。

function divide(a, b) {
  console.assert(b !== 0, 'ゼロ除算が発生しました。', a, b);
  return a / b;
}

console.log(divide(10, 2));
console.log(divide(10, 0));

divideという関数は、2つの数値を受け取って、その除算結果を返します。

ただし、第2引数が0の場合は、ゼロ除算エラーが発生してしまいます。

そこで、console.assert()を使って、第2引数が0の時だけエラーメッセージをログ出力するようにしています。

実行結果

5
ゼロ除算が発生しました。 10 0
Infinity

第2引数が0の場合だけ、エラーメッセージとともに引数の値が出力されていますね。

こうすることで、どんな値でゼロ除算が発生したのかが一目瞭然になります。

○サンプルコード10:console.count()で実行回数をカウント

console.count()は、その関数が呼び出された回数を数えてくれる便利なメソッドです。

同じラベルを指定した場合は、そのラベルごとに呼び出し回数を数えます。

例えば、次のようなコードを見てみましょう。

function greet(name) {
  console.count(name);
  console.log(`Hello, ${name}!`);
}

greet('Alice');
greet('Bob');
greet('Alice');

greet関数は、名前を受け取って挨拶を出力する関数です。

その際、console.count()を使って、その名前で何回目の呼び出しかを数えています。

実行結果

Alice: 1
Hello, Alice!
Bob: 1
Hello, Bob!
Alice: 2
Hello, Alice!

Aliceは2回、Bobは1回呼び出されていることがわかります。

関数が意図した回数だけ呼び出されているか確認する時などに役立ちそうです。

まとめ

ここまで、JavaScriptにおけるさまざまなデバッグ方法を見てきました。

PHPのvar_dump()のような組み込み関数はありませんが、console.log()やブラウザの開発者ツール、Node.jsのデバッグ機能など、多彩なデバッグ手段が用意されています。

よくあるエラーへの対処法を身につけ、console.assert()やconsole.count()といった便利なメソッドも活用すれば、JavaScriptのデバッグがきっと楽しくなるはずです。

最初は大変かもしれませんが、デバッグのコツをつかめば、JavaScriptの学習もぐんと捗るでしょう。

皆さんも、ここで紹介したテクニックを実際のコードに役立ててみてください。