JSLintオプション考察「++ and--」

2013年08月07日

カテゴリー:

++ and --」オプションは、++(インクリメント演算子)、または--(デクリメント演算子)の使用を許可するかどうかのオプションです。デフォルト(false)では、これらの演算子の使用は許可されません。

例えば、次のコードをJSLintでチェックした場合、このオプションがデフォルトのままだと、「Unexpected ‘++’.」という警告が出てしまいます。

var i = 0;

window.console.log(i++); //Unexpected '++'.

なぜいけないのか?

インクリメント、デクリメント演算子を使用すると、非常に簡潔にコードを書くことができますが、JSLintではなぜこれらの演算子を使用すると警告が表示されるのでしょうか?

JSLintの作者Douglas Crockford氏による著書によると、次の様な説明が書いてありました。

インクリメント、デクリメント演算子を使うと、非常に簡潔なコードを書くことができる。
しかしこの演算子は無謀なプログラムを書かせる原因にもなってしまう。深刻なセキュリティの脆弱性を引き起こすバッファオーバーランのバグの多くは、そうした無謀なコードによって引き起こされることが分かっている。
私自身の経験では++と--を使うと、コードが詰まりすぎ、トリッキーなものになりすぎ、そして不可解になりすぎる傾向がある。そこで私は、これらの演算子を今後使わないというルールを自分に課した。

引用元:JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス

これを見る限りでは、Douglas Crockford氏の個人的な見解色の強いルールのような気がしますが、一理あるとも思います。

インクリメントやデクリメント演算子は、さらに演算子をオペランドの前に置くプリインクリメント(++i;など)、オペランドの後ろに置くポストインクリメント(i++;など)があり、これらが1行のコード内に多用されていたりすると、たった1行のコードを「解読」しなければ読み解けないレベルになってしまいます。

ちょっと実際にはあり得ない例ではありますが、例えば以下の関数を実行すると、window.console.log(i);の出力はどうなるでしょうか?

(function () {
    "use strict";

    var i = 0,
        j = 0;

    i = i++ - ++i + j++ - --j;
    window.console.log(i);
}())

答えは「-2」です。
こういったコードに慣れている人であればなんてことない問題かもしれませんが、少なくとも私にとっては、もはやさらっと読めるレベルのものではなく、ミスも発生しそうです。
そう考えると、JSLintがインクリメント、デクリメント演算子を非推奨とするのも分かる気がします。

ただ、実際には殆どの場合、インクリメント、デクリメント演算子はfor文などのループ制御のために使われる程度で、上記のような極端な使い方をするケースなど無いでしょう。

いちいち

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

などと書くよりも

for (i = 0, len = 10; i < len; i++) { ... }

と書いた方がコードもスッキリするし、この程度のインクリメントの使い方であれば、ミスなどは発生しないと思うので、こちらの方が良い気もします。

結局のところ

++ and --」オプションをtrueにするかfalseにするかは、開発者自身、またはチームのコーディングスタイルに合わせて選択すれば良く、JSLintのオプション優先度的には低いと言えるでしょう。

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