これでできる! クロスブラウザJavaScript入門

第2回 完全版:ブラウザとデバッグ環境

この記事を読むのに必要な時間:およそ 7 分

デバッガの基礎知識

ここまで,FirefoxのFirebug,Safari/Chrome(WebKit)のWeb Inspector,OperaのDragonfly,IEの開発者ツールと紹介してきました。これらを使いこなす上で共通のチップスがいくつかありますので紹介します。

consoleオブジェクト

各デバッガは共通してconsoleオブジェクトを実装しています(Operaは10.50以降⁠⁠。しかし,そのメソッドはブラウザごとにまちまちで,現状は次のとおりです。

consoleメソッドの実装状況(2010年3月時点)

// 共通
console.log
console.warn
console.error
console.info
// Dragonfly以外
console.assert
// Web InspectorとDragonfly以外
console.clear
// FirebugとWeb Inspector
console.count
console.debug
console.dir
console.dirxml
console.group
console.groupEnd
console.markTimeline
console.profile
console.profileEnd
console.time
console.timeEnd
console.trace
// Firebugのみ
console.exception
console.groupCollapsed

今のところ,Dragonflyが最も少なく,IEの開発者ツール,Web Inspector,Firebugの順に種類が増えています。

なお,共通といっても,Firebugの入っていないFirefoxやIE 8以前,Opera 10.50以前などはconsoleオブジェクト自体が存在しません。デバッグ用のコードを残さないように注意しましょう。

debuggerステートメント

各デバッガはJavaScriptのステップ実行をサポートしています。ブレークポイントを設定してその位置で実行を止めて,ローカル変数をチェックするといったことが可能です。

このとき,動的に追加するスクリプトなどではブレークポイントの設置が難しいケースがあります。そんなときは,debugger;という行を追加しておくとその場所でブレークすることができます。なお,debuggerはECMAScript第3版(JavaScriptのベースとなる仕様)では予約語であり,ECMAScript第5版ではキーワードとなっているので,非対応ブラウザでもシンタックスエラーになることはなく,実行時に例外を投げることになります。デバッガ(IEのスクリプトエディタやVisual Studioなど)によっては,debuggerステートメントには対応していないが,例外が起こることによってブレークさせることもできます。

プロファイリング

OperaのDragonfly以外のブラウザはJavaScriptのプロファイリング機能を搭載しています。プロファイリングでは細かい単位でパフォーマンスをチェックすることができるので,是非試行錯誤してエンジンの傾向を探ってみてください。一見些細なことに思えるような部分でも調整してみると驚くほどにパフォーマンスが上がることもあります。なお,パフォーマンスの改善はこの連載でも扱う予定です。

IEとJScriptとメモリリーク

さて,最後に少しコアなお話をしたいと思います。1ページ目で「Service Pack 3を適用するとIE 6のJScriptのバージョンが5.6から5.7に変わる」と書きました。JScript 5.7はIE 7に搭載されたJScriptと同じバージョンです。バージョンが変わっているということは,大きな変更があるのかと思われることでしょう。しかし,実際には IE 6+JScript5.7 は,XMLHttpRequest が使えるわけでもなく,style.maxHeight に対応しているというわけでもありません。特に変化はないように思われます。

と,詳細はMicrosoftの公式ドキュメントであるInternet Explorer 6 for Windows XP SP2 および Internet Explorer 6 for Windows XP SP3 で修正される問題の一覧にあります。こちらかなりの数がありますが,多くがセキュリティ修正,クラッシュやフリーズの修正です。ただ,一点だけWindows XP ベースのコンピュータで JScript スクリプトを使用する Web ページを表示すると,Internet Explorer 6 でメモリ リークが発生するという(この連載にとって)重大な修正が含まれてます。実は,この修正の通りSP3適用前のIE 6では,クロージャーを使うとメモリリークが発生していました。HTML ページの DOM オブジェクトへの循環参照はメモリ リークが発生します。にあるリークパターンはこちらです(より簡略化してあります⁠⁠。

旧IE 6でのリークパターン

<html>
<body>
<div id="menu"></div>
<script>
hookup(document.getElementById('menu'));
function hookup(element){
  element.attachEvent('onmouseover', mouse);
  function mouse (){
    // クロージャでelementへの参照が残り続ける
  }
}
</script>
</body>
</html>

このようなシンプルなスクリプトでメモリリークが発生してしまうのは深刻な問題でした。回避策はありますが,対策をするとコードが非常に冗長になってしまいます。このバグが,SP3では修正されているのです。というわけで,この連載ではSP3適用を前提として,上記のようなパターンへのメモリリーク対策は省略させて頂きます。

と,もう一点JScriptのバージョンが5.6から5.7に変わることで影響が出る問題があります。

JScriptは条件付きコンパイルを実装しており,特殊なコメントを埋め込むことができます。この条件付きコンパイルでIEかどうかの判定や,JScriptのバージョンを調べることができます。

JScriptの条件付きコンパイル

/*@cc_on alert([
  @_jscript_version,
  @_jscript_build,
  @_win32,
  @_mac
]) @*/
// 5.8, 22960, true, NaN
var isIE = false/*@cc_on || true @*/; // IEを判定

しかし,前述の通り,JScriptのバージョンは5.6→IE 6,5.7→IE 7,5.8→IE 8と対応しなくなってしまっています。条件付きコンパイルでのバージョン判定には注意が必要です。なお,こういったバージョンを判定する方法はこの連載では極力しようをさけるようにします。その詳細は次回解説します。

まとめ

今回はブラウザ環境の準備でいっぱいとなってしまいました。しかし,JavaScriptに限らずウェブ開発に欠かせないツールなので,是非試して頂ければと思います。次回からはクロスブラウザ対応の心得と,実際の作業手順を紹介していきたいと思います。

著者プロフィール

太田昌吾(おおたしょうご,ハンドルネーム:os0x)

1983年生まれ。JavaScriptをメインに,HTML/CSSにFlashなどのクライアントサイドを得意とするウェブエンジニア。2009年12月より、Google Chrome ExtensionsのAPI Expertとして活動を開始。

URLhttp://d.hatena.ne.jp/os0x/