ブラウザのデベロッパツールのコンソールへlogを出力する方法と、
その際の注意点や解決策についてソースコード付きで解説します。
最終的にはlog出力の完成形として、
IEエラー回避、consoleオブジェクトの記述無し、デバッグ切り替え機能付きの
プラグインの作成まで順を追って解説致しますので、最後までお付き合い頂ければ幸いです。
JavaScript開発において、変数の中身の確認や、処理フローの状況を確認する為には、
今まではHTMLへ出力したり、alert()等で通知したりといった事が主流でした。
しかし、ブラウザの技術進歩により、かなりJavaScript開発の手助けとなる機能が充実して来ました。
そんな中、ブラウザのデベロッパーツールのJavaScriptコンソールへ
logを出力する事が可能となりました。
今回の記事では、そんなlog出力の方法と、Safari、ChromeやFirefox、各ブラウザでの互換吸収、IEへの対策方法等を
解説したいと思います。
alert()の様に、一回一回ボタンを押す必要も無く、HTML出力の様にレイアウト崩れを気にしたり、
ロギング環境を構築する手間も必要ありません。
今回解説するlog出力方法を身につければ、きっと今後のJavaScript開発が加速するはずです。
- JavaScriptコンソールへlogを出力してみよう!
- 他にもあるlog出力系便利メソッド!
- consoleが使えないブラウザでもエラーが発生しない様にしよう
- 長いオブジェクト名を短縮しよう
- コンソールへのlog出力の有効・無効を設定しよう
- log出力の完成形!IEエラー回避&console記述無し&デバッグ切り替え機能付き
JavaScriptコンソールへlogを出力してみよう!
JavaScriptコンソールへのlog出力の方法です。
JavaScriptコンソールへlog出力するには、consoleオブジェクトを使用します。
consoleオブジェクトには、様々なメソッドが用意されており、
まずはその中でも簡単で、単純にlog出力出来る『log()』の使い方です。
// 引数にコンソールに出力したいメッセーを渡す console.log( "hoge" ); // 変数もlog出力可能 var moge = "moge"; console.log( moge ); // オブジェクトもlog出力可能 var profile = { name:"hamada", country:"japan", sex:"man" }; console.log( profile ); // 引数と複数与える事も出来ます console.log( "hoge", moge, profile );
上記を実行すると、下記の様にlog出力します。
とても簡単ですね。
キャプチャ画像はFirefoxのFireBugのものですが、
Chromeの場合はのデベロッパツールのコンソール内に出力されます
Safariでは、設定⇒詳細⇒『メニューバーに"開発"メニューを表示』にチェックを入れた後に、
メニューバーにある『開発』から『エラーコンソールを表示』で表示されますコンソールに出力されます。
IEでは、『ツール⇒開発者ツール⇒デバッグの開始』にてログを確認する事が出来ます。
他にもあるlog出力系便利メソッド!
『log()』メソッドは、単純なlog出力を行ないますが、他にも便利なメソッドが用意されています。
ChromeやSafariとFirefoxのFireBugでは、その関数毎に動作が違うので注意が必要です。
FirefoxのFireBugの方が機能が豊富なので、この先は基本的にFirefoxのFireBugを元に解説し、
ChromeやSafariについては違いの部分だけ注記します。
また、基本的には、console.log()以外はIEでは動かないと思っておいて間違いないでしょう。
IEで表示された時にエラーにならないようにする対策は、後半に改めて解説致します。
■consoleに用意されている便利メソッド一覧
console.log( obj [, ...] ) | コンソールにログを出力 (Chromeでは行番号も出力される) |
---|---|
console.debug( obj [, ...] ) | 行番号と共にログを出力 (Chromeでは青文字虫眼鏡アイコン)(Safariでは.logと同じ) |
console.info( obj [, ...] ) | 行番号と共に、先頭に『 i 』のアイコンをつけてログを出力 (Chrome,Safariでは.logと同じ) |
console.warn( obj [, ...] ) | 行番号と共に、先頭に『 ! 』のアイコンをつけてログを出力 |
console.error( obj [, ...] ) | 行番号と共に、先頭に『 × 』のアイコンをつけてログを出力 |
console.dir( obj ) | オブジェクトのプロパティと値を全てコンソールへ出力 |
console.trace() | コールした時に呼ばれている関数名をコンソールへ出力 |
console.assert( exp [, ...] ) | expがfalseと評価された場合、第2引数以降をコンソールへ出力 |
console.dirxml( node ) | 引数にDOMノードやHTMLを渡すと、XMLツリー構造を表示 (Chromeでは全プロパティが出力) |
console.group( obj [, ...} ) | console.groupEnd()が呼び出されるまでを一つのグループとして出力 |
console.groupEnd() | console.groupで開始されたグルーピングを終了 |
console.time( tag [, reset] ) | console.timeEnd()が呼び出されるまでタイマーを回します。 第二引数へtrueをセットすると、計測をリセット出来ます |
console.timeEnd( tag ) | console.timeからの経過時間を出力 |
console.profile() | 実行された関数の解析をスタートさせます。 |
console.profileEnd() | console.profile()で開始された解析作業を停止して、結果を出力 (Chrome,Safariでは詳細までは表示されません) |
console.count( [label] ) | console.countが呼ばれた回数を出力。カウント対象にラベル付けも可能 (Chrome,Safariではそのままではインクリメントされません。 後述するconsoleを省略するやり方を行うと、インクリメントされる様になります) |
では、具体的にそれぞれのメソッドを起動して見ましょう。
テストコードは下記の様に行います
// テスト実行関数 function test_fnc(){ console.log( "ログを出力" ); console.debug( "行番号と共にログを出力" ); console.info( "行番号と共に、先頭に『 i 』のアイコンをつけてログを出力" ); console.warn( "行番号と共に、先頭に『 ! 』のアイコンをつけてログを出力" ); console.error( "行番号と共に、先頭に『 × 』のアイコンをつけてログを出力" ); console.log( "オブジェクトのプロパティと値を全てコンソールへ出力" ); console.dir( { code:"01", message:"オブジェクトのプロパティと値を全てコンソールへ出力", user:{ name:"hamada", country:"japan", sex:"man" } } ); console.log( "コールした時に呼ばれている関数名をコンソールへ出力" ); console.trace(); console.log( "expressionがfalseと評価された場合、第2引数以降をコンソールへ出力" ); var expression = 3; console.assert( expression <= 5, "expressionは5以下ではありません" ); console.assert( expression >= 5, "expressionは5以上ではありません" ); console.log( "引数にDOMノードやHTMLを渡すと、XMLツリー構造を表示" ); console.dirxml( document.head ); console.group( "console.groupEnd()が呼び出されるまでを一つのグループとして出力" ); console.log( "group1" ); console.log( "group2" ); console.log( "group3" ); console.groupEnd(); console.log( "console.groupで開始されたグルーピングを終了" ); console.log( "console.timeEnd()が呼び出されるまでタイマーを回します。第二引数へtrueをセットすると、計測をリセット出来ます" ); console.time( "timer" ); console.log( "console.timeからの経過時間を出力" ); console.timeEnd( "timer" ); console.log( "console.countが呼ばれた回数を出力。カウント対象にラベルを付ける事も可能" ); console.count( "count1" ); console.count( "count1" ); console.count( "count1" ); console.count( "count1" ); } console.log( "実行された関数の解析をスタートさせます。" ); console.profile(); // テストを実行 test_fnc(); console.log( "console.profile()で開始された解析作業を停止して、結果を出力" ); console.profileEnd();
上記コードを起動すると、下記の様な出力結果となります。
テストコードと比較してみて、メソッド毎の実行結果の違いをイメージして下さい。
FirefoxのFireBug
実行結果キャプチャ
Chrome
実行結果キャプチャ
Safari
実行結果キャプチャ
consoleが使えないブラウザでもエラーが発生しない様にしよう
consoleオブジェクトが存在しない場合、console.log()メソッドが使えない場合、
IE8,IE9にて開発者ツールが立ち上がっていない場合、
IE6,IE7以前にてconsole自体使えない場合では、console.log()等を記述したままですと
エラーになってしまいます。
開発時には良いのですが、実際にリリースした後にユーザが見た時に
エラーが発生してしまったら大変です。
しかし、開発とリリースが細かく行われるWEBアプリにおいて、
一回一回デバッグコードをコメントアウトするのはとても大変です。
ですので、この章ではデバッグコードを残していても、
エラーが出ない様にする対処法について解説します。
まず、console.log()からエラーが出る原因としては、
二つ考えられます。
一つ目が、『consoleって何?そんなの無いよ』といった
consoleオブジェクトが無いというエラー
二つ目が、『console.log()っていうメソッド知らないよ』といった
log()メソッドの定義が無い場合のエラーです。
簡単に説明しますと、元となるオブジェクトが無い時、指定のメソッドが無い時に
エラーが発生します。
どちらも共に、あるはずの物が無いというエラーですので、
無い場合は代わりのものを用意してあげればエラーにはならず、
用意したものの動作を行います。
例えば、下記の様な実装になるでしょう。
// consoleが使えない場合は空のオブジェクトを設定しておく if( typeof window.console === "undefined" ){ window.console = {}; } // console.logがメソッドでない場合は空のメソッドを用意する if( typeof window.console.log !== "function" ){ window.console.log = function(){}; }
コメントにも書きました通り、consoleオブジェクトが存在しない場合は
consoleに対して空のオブジェクトを設定します。
consol.log()メソッドが存在しない場合は、空の関数をセットします。
consol.log()と同じく、前述で列挙いたしましたメソッド一覧の中で
使用しているものがあるのであれば、そのメソッドでも同じ様に
空の関数を設定する処理を書いておいた方が良いでしょう。
これらの指定は、console関係を使用する前に処理が通っている必要があります。
念の為に、一番初めに読み込んでおくと良いでしょう。
外部ファイルとして扱いやすい様に、他メソッドと共に指定した状態を下記に記しますので、
コピペにてお使い頂ければ幸いです。
(function(){ // consoleが使えない場合は空のオブジェクトを設定しておく if( typeof window.console === "undefined" ){ window.console = {}; } // console.@@がメソッドでない場合は空のメソッドを用意する if( typeof window.console.log !== "function" ){ window.console.log = function(){}; } if( typeof window.console.debug !== "function" ){ window.console.debug = function(){}; } if( typeof window.console.info !== "function" ){ window.console.info = function(){}; } if( typeof window.console.warn !== "function" ){ window.console.warn = function(){}; } if( typeof window.console.error !== "function" ){ window.console.error = function(){}; } if( typeof window.console.dir !== "function" ){ window.console.dir = function(){}; } if( typeof window.console.trace !== "function" ){ window.console.trace = function(){}; } if( typeof window.console.assert !== "function" ){ window.console.assert = function(){}; } if( typeof window.console.dirxml !== "function" ){ window.console.dirxml = function(){}; } if( typeof window.console.group !== "function" ){ window.console.group = function(){}; } if( typeof window.console.groupEnd !== "function" ){ window.console.groupEnd = function(){}; } if( typeof window.console.time !== "function" ){ window.console.time = function(){}; } if( typeof window.console.timeEnd !== "function" ){ window.console.timeEnd = function(){}; } if( typeof window.console.profile !== "function" ){ window.console.profile = function(){}; } if( typeof window.console.profileEnd !== "function" ){ window.console.profileEnd = function(){}; } if( typeof window.console.count !== "function" ){ window.console.count = function(){}; } })();
長いオブジェクト名を短縮しよう
log出力は、開発時には沢山使う事でしょう。
しかし、頻繁に使うには『console』というのは少し長いオブジェクト名な気がします。
そこで、consoleオブジェクトへ定義されているメソッドを、そのままwindowメソッドへと定義しなおし、
オブジェクト名無しで呼び出す事が出来たら便利そうです。
早速実装してみましょう。
// 置換対象のメソッドを配列として保持する var methods = [ 'log', 'debug', 'info', 'warn', 'error', 'dir', 'trace', 'assert', 'dirxml', 'group', 'groupEnd', 'time', 'timeEnd', 'count', 'profile', 'profileEnd' ]; // 各メソッドをwindowへ直接追加して行く for( var i in methods ){ (function( m ){ if( console[m] ){ window[m] = function(){ console[m].apply( console, arguments ); }; } })( methods[i] ); }
それぞれのメソッドを初めに配列へ纏めて、
順にwindowへ同じ名前で登録しています。
もし、既にあるプロジェクトへ組み込む際に、メソッド名のバッティングが有る場合は、
初めの宣言の所で選別して下さい。
そして、前述いたしましたconsole.count()ですが、
Chrome,Safariではインクリメントされませんでしたが、この実装を行う事でインクリメントされる様になります。
(FireBugではインクリメントされた最終値が出力されますが、Chrome,Safariではインクリメント経歴も追って出力されます)
コンソールへのlog出力の有効・無効を設定しよう
更に事前設定を行う事で、log出力用の記述が残っていたとしても、
コメントアウトせずに有効・無効を切り替える事が出来ます。
これにより、リリース時には、余計なデバッグコードの出力を見せずに済みます。
デバッグの有効・無効を切り替えるには、
単純にメソッドを空振りさせる事で対応出来ます。
前述で記しましたIE対策においての空の関数を設定する方法と同じように、
デバッグモードなら通常メソッドを設定し、デバッグモードが解除されていたら空のメソッドを定義する。
この様なやり方でも可能ですが、少し面倒です。
そこで、先程解説しましたconsoleオブジェクトを記述しないでメソッドを呼ぶ実装に加えて
デバッグの判定も追加したいと思います。
// デバッグモード切替 var debugMode = false; // 置換対象のメソッドを配列として保持する var methods = [ 'log', 'debug', 'info', 'warn', 'error', 'dir', 'trace', 'assert', 'dirxml', 'group', 'groupEnd', 'time', 'timeEnd', 'count', 'profile', 'profileEnd' ]; // 各メソッドをwindowへ直接追加して行く for( var i in methods ){ (function( m ){ if( console[m] && debugMode ){ window[m] = function(){ console[m].apply( console, arguments ); }; } // debugModeがfalse,もしくは該当メソッドが存在しない場合は、空のメソッドを用意する else{ window[m] = function(){}; } })( methods[i] ); }
log出力の完成形!IEエラー回避&console記述無し&デバッグ切り替え機能付き
更にカスタマイズを続けましょう。
コレまでに、consoleを記述しないでメソッドを呼ぶ実装に加え、
デバッグモードの切り替え機能を実装しました。
そこへ、更にIE等でconsoleが使えない場合のエラー回避方法も混ぜ込みたいと思います。
IEでのエラー回避では、ポイントが二つ有ると解説させて頂きました。
一つ目がconsoleオブジェクトが存在しない場合。
こちらは、そのまま前述の通りに追加したいと思います。
そして、二つ目がconsole.log()等のメソッドが存在しない場合。
これは、デバッグモード判定の所に混ぜれば、存在しない場合は空のメソッドを
当て込む事で解決しそうです。
では早速完成形の実装を下記に明記します。
そのままコピペでも使用出来る用にしていますので、
どうぞお使い下さい。
(function(){ // デバッグモード切替 var debugMode = false; // 置換対象のメソッドを配列として保持する var methods = [ 'log', 'debug', 'info', 'warn', 'error', 'dir', 'trace', 'assert', 'dirxml', 'group', 'groupEnd', 'time', 'timeEnd', 'count', 'profile', 'profileEnd' ]; // consoleが使えない場合は空のオブジェクトを設定しておく if( typeof window.console === "undefined" ){ window.console = {}; } // 各メソッドをwindowへ直接追加して行く for( var i in methods ){ (function( m ){ // consoleにある?デバッグモードは有効?consoleのものは関数? if( console[m] && debugMode && typeof console[m] === "function" ){ window[m] = function(){ console[m].apply( console, arguments ); }; } // debugModeがfalse,もしくは該当メソッドが存在しない場合は、空のメソッドを用意する else{ window[m] = function(){}; } })( methods[i] ); } })();
以上で、各ブラウザへの対応策も実装され、更にconsoleを省略する事で使いやすく、
そしてリリース時にもデバッグモードの切り替えだけでlog出力の有効・無効を切り替える事が出来るという
とても便利なライブラリが出来上がったかと思います。
今回は、コレをlog出力サポートの完成形とさせて頂きますが、
更にこんな機能を付けた方が良いのでは?
そこんところ間違ってるぞ?
こうした方がスマートだ!
等等、ご意見ご感想はコメント欄へ
どしどし書き込んで頂ければ幸いです。
今後も、更に有益な情報と、有用なツールを発信して行きたいと思います。