JSLintオプション考察「messy white space」

2013年09月17日

カテゴリー:

「messy white space」は、JavaScriptコード中における空白文字(スペースやタブ)の取り扱いを厳密にチェックするかどうかのオプションです。デフォルト(false)では、正しく空白文字が使われていないと警告が表示されます。

ちなみに、「messy」とは日本語で「汚い」とか「乱雑な」という意味で、「white space」は空白文字(半角スペース、タブ、改行文字)のことです。つまり、「messy white space」は「乱雑な空白文字(をチェックする)」という意味になりますね。

このオプションが有効な場合、JavaScriptコード内の空白文字の扱いは正しいフォーマットで統一されていなければなりません。正しいフォーマットとは、半角スペースの挿入位置や、インデントが適切であるということです。

例えば次のコードは、一見問題なさそうに見えますが、コードの1行目で「Expected exactly one space between ‘)’ and ‘{‘.」という警告が表示されます。これは、「test()」とその後の「{」の間にスペースを入れなければならない、という意味です。

function test(){    //Expected exactly one space between ')' and '{'.
    "use strict";
    return false;
}

上記の例以外にも、「JavaScriptパターン ―優れたアプリケーションのための作法」では、空白の挿入位置には以下の様なルールが記載されていました。

空白を適切に使うと、コードの読みやすさと一貫性が向上します。英作文でカンマやピリオドの後には空白を置きます。JavaScriptも同じ理論に従っていて、リストの区切り(カンマと同じです)や文の終わり(一つの考えが完結したのと同じです)の後には空白を置きます。
空白を使うべき状況は以下の通りです。

  • forループの式を区切るセミコロンの後

    for (var i = 0; i < 10; i += 1) {...}

  • forループで複数の変数(i と max)を初期化しているとき

    for (var i = 0, max = 10; i < max; i += 1) {...}

  • 配列の要素を区切るカンマの後

    var a = [1, 2, 3];

  • オブジェクトプロパティを区切るカンマの後。プロパティ名とその値を区切るコロンの後

    var o = {a: 1, b: 2}

  • 関数の引数を区切る

    myFunc(a, b, c)

  • 関数宣言の波括弧の前

    function myFunc() {}

  • 無名関数の場合、functionの後

    var myFunc = function () {};

演算子とその演算対象の間でも空白を使いましょう。つまり、+, -, *, =, <, >, <=, >=, ===, !==, &&, ||, +=, などの後に空白を置くということです。


最後に波括弧と空白の組み合わせについて説明しておきます。以下の状況で空白を使います。

  • 関数、if-else、ループ、オブジェクトリテラルで波括弧を開く({)の前。
  • 波括弧閉じ(})と else や while の間。

引用元:JavaScriptパターン ―優れたアプリケーションのための作法

なんだかんだで、色々と細かくルールがあるようですが、私はこれらのルールを暗記する必要はないと思います。
コードをJSLintでチェックすればスペースの抜けなどは全てチェックしてくれるので、警告が出たら修正するという作業を繰り返していくうちに、自然と正しいコーディングが身についてくると思うからです。(私自身、空白文字に関するルールはほとんど暗記しませんでしたが、JSLintを使うようになってから自然と身についてきたように思えます。)

ちなみに、垂直方向の余白(改行)についてはどうなんでしょう??
私はよく if や for ループのブロックの前後に余白(改行)を入れるのですが、実際のところこれに関してはルールなどはあるのかが気になりましたが、「JavaScriptパターン ―優れたアプリケーションのための作法」によると

垂直方向の余白によってコードが読みやすくなる点については、あまり考慮されていません。考えを区切るときに段落を使うのと同様に、コードの単位を空行を使って区切りましょう。

引用元:JavaScriptパターン ―優れたアプリケーションのための作法

…だそうです。
要は「縦の余白はお好みで」という解釈で良いと思います。



さて、この「messy white space」オプションですが、実はこのオプションには非常に悩ましい問題があります。
それは、インデントにタブを使用できなくなる(タブを使うと警告が出る)ということです。
理由はJSLintではコードのインデントにスペースの使用を強制してくるからです。

なぜタブが禁止なのか?については詳しいことは分かりませんが、おそらくJSLintの作者(ダグラス・クロックフォード氏)による個人的な好みなのではないかと思います。

少し余談になりますが、JSLintは往々にしてこのように作者の個人的見解が持ち込まれている部分があるように思えます。こういった理由から、JSLintではなく、同じくJavaScriptのコードチェックツールである「JSHint」へ乗り換えるユーザも多いようです。このことについては、JSLint から JSHint をフォークした理由(翻訳) |黒くないすべてのものはカラスではないに詳しく書かれていました。

とにかく私はこれまでインデントはタブ派だったので、正直これには困りました。どんなに正しいコードでも、それをJSLintに通した途端に警告の嵐になるからです。(警告の内容は全て「インデントにはスペースを使え」というもの)

ちなみに、タブを使ったインデントを許可するような個別オプションはありません。この「messy white space」オプションを true にすれば、警告は出ませんが、それだと(インデント以外の)スペースのチェックも行われなくなってしまうので、これも解決になっていません。

要するに…

インデントは全てスペースに置き換えるか、JSLintを使うのをやめるかの二択

ということになってしまいます。

結局私は、タブインデントを最終的にスペースに一括置換する方法で、JSLintを使い続けることを選択しましたが、なんだかJSLintの軍門に下った気がしました・・・

「インデントをどうすべきか?」は議論の絶えないテーマですが、そうまでしてJSLintを使い続ける理由はないと思うのであれば、JShintを使用することを検討してみるのも良いと思います。(JSHintではタブインデントは許可されています)

最後に、この「messy white space」オプションに関しての私なりのまとめですが、インデントにスペースを使うことに問題が無いのであれば、デフォルト(false)のままにしておくべきです。どうしてもタブインデントを使い続けたいのであれば、このオプションを無効(true)にするか、JSHint等の他のチェックツールを使うことを検討してみてください。

JSLintのオプション一覧ページへ