ここではJavaScriptコードの品質チェックツール「JSLint」について紹介します。
JSLintはWebベースのツールなので、ブラウザがあればすぐにでも利用することができます。
JSLintは、私たちのJavaScriptコードの検証を行い、推奨されない書き方(アンチパターン)や構文エラー、使用されていない変数、未定義の変数の使用といった潜在的な問題が見つかった際に警告してくれます。
コードをJSLintでチェックすることはとても推奨されているそうですよ。また、JSLintはJavaScriptのコードチェックツールとして、デファクトスタンダード(事実上の標準)になっていると思われます。
このブログではコーディングの作法などについても触れていこうと思うのですが、兎にも角にもまずはこのツールを使う「癖」をつけておくことをお勧めします。
それは「習うより慣れよ」で、コードを書いたら必ずJSLintのチェックを通すように癖づけしておけば、自然と正しいコーディングが身に付いてくると思うからです。
最初は大量のエラー(警告)に戸惑うかもしれませんが、エラーの修正を繰り返していくうちに、だんだんとJavaScriptコーディングの作法が見えてくるはずです。
ちなみに、JSLintは公式なものは英語版のみの提供となりますが、使い方は説明が不要なほどシンプルですので、オプション項目とエラーメッセージの意味さえ理解出来れば英語版で十分だと思います。
JSLintの基本的な使い方
JSLintはWEBベースのツールなので、以下のページにアクセスして、テキストフォームにチェックしたいコードを貼り付けるだけです。簡単ですね。
▼JSLint,The JavaScript Code Quality Tool
http://www.jslint.com/
ただ、実際に使用する際には、いくつかのオプションの指定と、定義済みのグローバル変数を宣言しておくことになると思います。
オプションを指定せずに、すべてをデフォルト設定のままにしておくと最も厳しいチェックとなります。
ですが、個人的にはそれだと制約がありすぎて、ちょっとコードが書きづらい感じがするので、いくつかのオプション指定(制約の解除)をしています。
でも解除するオプションが多すぎてもJSLintを使う意味がなくなってしまうので、解除するオプションは必要最低限にとどめておくべきです。
個人的には、Webブラウザでの動作を前提としている(ほとんどの場合がこれに該当すると思いますが)のであれば、「Assume a browser」は true にしておいても良いと思います。
その他、現状では私は下記のオプションを解除しています。
- Tolerate continue
- Tolerate ++ and —
例えばjQueryを使用していて、次の様なコードをチェックするとします。
$(function () { "use strict"; var obj = $("p"); obj.text("test"); });
このコードをJSLintでチェックする時に「定義済みグローバル変数」が未入力だと下図のようなエラーが表示されるはずです。
これは「$」という変数は定義されていないよ!という意味です。
jQueryを使用すると、「$」「jQuery」という2つのグローバル変数が使われるので、この場合JSLintでチェックする際に「定義済みグローバル変数」にこの2つのグローバル変数を予め宣言(入力)しておく必要があります。
(複数のグローバル変数を宣言するには、スペース区切りで入力していきます。)
「定義済みグローバル変数」に必要なグローバル変数をセットしておき、再度チェックを実行して、上の図のような「Errors」の表示が出なければチェックOKということになります。
まずは自分のコードでどのくらいのエラーが出るのか、試してみてくださいね。
オプション一覧
JSLintでは様々なオプションが指定可能ですが、オプションの名前を見ただけではそれが何なのかが良く分かりません。そこで、これらの各オプションについて、
- オプションの意味
- なぜそのような制約があるのか?
- エラー(警告)が出た場合の対応方法
- そのオプションは true にすべきか false にすべきか?
といった点をまとめたもの(若干、個人的な見解も含まれますが)をそれぞれ個別エントリにて作成しました。
以下のオプション一覧のタイトルリンクをクリックすれば各エントリに遷移しますので良かったら参考にしてみてください。
Assume(JavaScript動作環境の定義)
JSLintのオプショングループ「Assume」ではJavaScriptの動作環境を定義します。
a browser | DOMやwindowオブジェクトのようなブラウザを前提としたホストオブジェクトを定義済みとみなします。 |
---|---|
CouchDB | 「CouchDB」上でJavaScriptを利用する場合に、この環境特有のグローバルオブジェクト等を定義済みとみなします。 |
console,alert, … | 「window.alert~」「window.console~」の「window.」部分を省略して記述することを許可します。 |
Node.js | 「Node.js」上でJavaScriptを利用する場合に、この環境特有のグローバルオブジェクト等を定義済みとみなします。 |
Rhino | 「Rhino」上でJavaScriptを利用する場合に、この環境特有のグローバルオブジェクト等を定義済みとみなします。 |
Tolerate(制約の解除)
JSLintのオプショングループ「Tolerate」ではJSLintのコードチェックにおける「規制緩和」を行います。
assignment expressions | if や while といったステートメントの条件式の中に代入式を書くことを許可するかどうかを指定します。 |
---|---|
bitwise operators | ビット演算子の使用を許可するかどうかを指定します。 |
Google Closure | Googleの提供するJavaScriptライブラリである「Closure Library」の使用を許可するかどうかを指定します。 |
continue | for や while といったループ内でcontinue文の使用を許可するかどうかを指定します。 |
debugger statements | debugger ステートメントの使用を許可するかどうかを指定します。 |
== and != | 比較演算子「==」「!=」の使用を許可するかどうかを指定します。 |
eval | eval() やnew Function() といった、文字列をJavaScriptコードとして評価する機能の使用を許可するかどうかを指定します。 |
unfiltered for in | for in ループ内において、「hasOwnProperty」メソッドによるプロパティのフィルタリングを強制するかどうかを指定します。 |
uncapitalized constructors | 関数名が小文字で始まるコンストラクタ関数の定義を許可するかどうかを指定します。 |
dangling _ in identifiers | アンダースコア( _ )から始まる変数名(または関数名)を許可するかどうかを指定します。 |
++ and — | ++(インクリメント演算子)、または–(デクリメント演算子)の使用を許可するかどうかを指定します。 |
. and [^ … ] in /RegExp/ | 正規表現のパターンにおいて、「.」、および「[^~]」の使用を許可するかどうかを指定します。 |
unused parameters | 宣言されているにもかかららず、一度も使用されていない変数の存在を許可するかどうかを指定します。 |
missing ‘use strict’ pragma | JavaScriptコードをstrictモード(厳格モード)で実行することを表す「”use strict”宣言」の未使用を許可するかどうかを指定します。 |
stupidity | Node.jsを利用する際に、「~Sync」という名前のメソッドの利用を許可するかどうかを指定します。 |
inefficient subscripting | オブジェクトのプロパティを参照する際、参照するプロパティ名が動的ではなく、静的に決定されているにもかかわらず、ブラケット([ ])を用いたプロパティ参照をすることを許可するかどうかを指定します。 |
TODO comments | JavaScriptコード中の「TODOコメント」を無視するかどうかを指定します。 |
many var statements per function | 関数内に複数のvar文を使用することを許可するかどうかを指定します。 |
messy white space | JavaScriptコード中における空白文字(スペースやタブ)の取り扱いを厳密にチェックするかどうかを指定します。 |
JSLintを使うときの心構え
かなり厳しいチェックが行われるため、中途半端な気持ちで利用すると心が折れそうになります。
かくいう私も当初、(特に根拠はないのですが)それなりに正しいコードを書いているつもりでした。
JSLintというツールがあると知った時、コードの問題を発見するためというよりは「自分のコードが正しいと証明するため」という甘い考えで利用しようとしていました。
JSLintのドキュメントには、「Warning: JSLint will hurt your feelings.」(=警告!JSLintはあなたの気持ちを傷つけるだろう)などという脅し文句がご丁寧に添えられていますが、「まぁ、俺には関係ないし」とスルーしながら、いざコードチェック開始。
その1分後。
お前に俺の何が分かるんだ!!
っていうか、このツールの方がバグってんじゃないの??(以下略)
と叫んでいる自分。そして画面には警告の嵐。
しかもコードの20%しかチェックしていないのに、エラー表示数の上限(デフォルトで50個)に達したためチェックを終了しました!みたいなことが書かれている。。
私はドキュメントに書かれている通りに傷つけられた後、「JSLint使うのやめようかな」などと考えながらしばらくネット上を徘徊していると、私と同じようにJSLintに傷つけられた人たちが結構いることに気づきました。
そして、傷つきながらも必死に戦っている人たちがそこにいました。
そんな人たちの奮闘記に励まされ、私も画面に表示された大量のエラーをよくよく見てみると、エラーの数こそ多いものの同じミスを何度もしているということに気づきました。しかも、それらのエラーの大半はスペースやインデントの位置が違う、といったような簡単に修正できるものだったのです。
エラーメッセージの意味を調べ、それらを1つ1つ手作業で修正していくとみるみるエラーの数が減っていきます。
ある意味これはこれで気持ちがいいなと思いながらコードの修正を重ねていき、ようやくコードチェックをパスすることができました。
JSLintのチェックでは、エラーが出るのが当たり前だと思っておいた方が良いでしょう。
コードをチェックする → エラーが出る → 修正する → またコードをチェックする・・・
このサイクルを繰り返していくことで、自分が犯しがちななミスに気づかせてくれます。そして、自然にJavaScriptコーディングにおける「正しい作法」が身についてくるでしょう。
これこそがJSLintを使う最大のメリットだと私は思います。
最初はこのツールに不快な思いをさせられることと思いますが、慣れてくると逆にJSLintのチェックを通さないと気持ちが悪くなるかもしれません(少なくとも私はそうです)。
もしそうなったら、それはきっとJavaScriptマスターへの近道を歩み始めている証拠だと思いますよ。