JavaScriptは他のプログラミング言語に比べ特に柔軟性のある言語だと思います。そのため、コーディングスタイルも人それぞれです。
これは、目的を遂げるための手段が非常に多く用意されているとも言えますが、JavaScript初級者にとってはこの柔軟性がかえってネックになったりもします。つまり、「どのようなコーディングがベストなのか?」ということが、とても分かりづらいのです。(私がそうでした)。
JavaScriptのコーディングスタイルに正解、不正解などは無いかもしれませんが、推奨されているコーディングスタイル(コーディングパターン)はあります。JavaScriptのような柔軟性に富んだ言語を覚える場合、このコーディングパターンを身に着けていくことが上級者への近道だと私は思います。
今回紹介する「単独varパターン」もこのコーディングパターンの1つです。
単独varパターンはJavaScriptのコーディングパターンの中でも最も実践しやすいパターンですので、是非取り入れてみることをお勧めします。
ちなみに、JavaScriptのコードチェックツールJSLintでは、この単独varパターンを適用していないと「Combine this with the previous ‘var’ statement.」という警告が表示されてしまいます。
「単独varパターン」とは?
「単独varパターン」とは、関数内でローカル変数を宣言する際に使用するvar文を1つにまとめるパターンです。
通常、関数内で複数のローカル変数を宣言する場合、下記の様にするケースが多いかと思います。
function func() { var a = 1; var b = 2; var sum = a + b; //関数の本体... }
上のコード例では、ローカル変数 a、b、sum があり、それぞれvar文を使用して宣言しています。
このコードに単独varパターンを適用すると、以下のコードになります。
function func() { var a = 1, b = 2, sum = a + b; //関数の本体... }
変数を宣言する度にvar文を使うのではなく、複数の宣言をカンマで区切って全ての変数宣言をvarの1文で済ませます。
ここで重要なのは、関数内で使用する「全ての変数」を単一のvar文で宣言することです。
例えば次のコードは1つのvar文で複数の変数を宣言していますが、var文が2つありますね。これは「単独varパターン」ではありません。
//アンチパターン function func() { var a = 1, b = 2, sum = a + b; var c = 3, d = 4, total = c + d; //関数の本体... }
単独varパターンを適用する際は、初期値で変数を初期化しておく方が良いでしょう。その方が変数の使用意図が明確になるからです。
//変数の初期化の例 function func() { var a = 0, //数値 flg = false, //真偽値 obj = {}, //オブジェクト ary = []; //配列 //関数の本体... }
また、次の様に変数宣言の際に処理や関数を書き込むことも可能です。
function func() { var elm = document.getElementById("result"), style = elm.style, getStyle = function() { return style; }; }
単独varパターンのメリット
単独varパターンには次の様なメリットがあります。
- 関数の先頭で、その関数で使用される全てのローカル変数が宣言されるため、必要とされる変数が一目で分かるようになり、コードの見通しも良くなる
- 変数を定義する前にその変数を使用してしまう「変数の巻き上げ」という論理上のエラーを予防できる。 →知らないと怖い「変数の巻き上げ」とは?
- 宣言する変数を覚えるのに役立ち、そのためグローバルを最小にできる。
- コード量が減る。
個人的な意見ではありますが、単独varパターンを適用することによるデメリットは無いと思います。jQuery本体のソースコードを見てみると、やはり単独varパターンで書かれていました。
単独varパターンは導入しやすいパターンですので、積極的に採用すべきでしょう。
ループ用変数はどうする?
次のコードの様に、for文の中でvarによる変数宣言をしているケースも多いと思います。
function func() { var sum = 0; for (var i = 0; i < 10; i++) { sum += i; } return sum; }
こういったループ内で使用されるループ用変数はどう扱うべきか、ということについて私は最初少し悩みました。ループ用変数も単独var文の中に含めた方が良いのでしょうか?
結論から言うと単独varパターンはあくまでも「単独var」、つまり関数の中にvar文は1つということなので、ループ用変数だろうが何だろうが全て関数の先頭のvar文の中で宣言しなければなりません。
ですので、上のコードは単独varパターンではないということになります。(※ちなみに、JSLintで上記のコードをチェックすると警告が出ます。)
上記のコードを単独varパターンに置き換えると次の様になります。
function func() { var sum = 0, i = 0; for (i = 0; i < 10; i++) { sum += i; } return sum; }
余談:コメントの位置について
単独varパターンについての説明は以上になりますが、これに関連した余談、、というかものすごく細かいことなんですが私が少し迷ったことを書いておきます。(ここに書くことはあくまでも私の個人的見解ですので、決して「こうした方が良い」といった類のものではありません。)
例えば次のコードを見てください。これは単独varパターンを適用していない状態のコードです。
function func() { //変数aのコメント var a = 0; //変数bのコメント var b = 0; //変数cのコメント var c = 0; //関数の本体... }
上記のコードの様に、各変数についてその用途などのコメントを記述していくケースは多いと思います。
単独varパターンの場合、上記のようなコメントはどのように書けば良いのでしょうか?
まずは単独varパターンを適用して、何も考えずに行頭からコメントを挿入してみます。
function func() { //変数aのコメント var a = 0, //変数bのコメント b = 0, //変数cのコメント c = 0; //関数の本体... }
コメントの書き出し位置が揃っていないため、なんだか気持ち悪いですね。
私が参考にしている書籍「JavaScriptパターン~優れたアプリケーションのための作法~」にちょうど同じようなコード例があったので、そちらの書き方に習ったものが下記になります。
function func() { //変数aのコメント var a = 0, //変数bのコメント b = 0, //変数cのコメント c = 0; //関数の本体... }
なんだかこちらの方がすっきりしているような気がします。
書籍では、こういった「コメントの書き出し位置」については、特に言及はされていなかったので、おそらくパターンなどはないのだと思います。また、コメントの性質によっては上記のコード例のような書き方だと都合が悪いケースなどもあるかもしれません。ですので結局は「ケースバイケース」ということだと思いますが、基本的なパターンとしては、上記のコード例のような書き方を私は採用しています。
まぁ、いずれにせよ重要なのはコード全体でルールが統一されていることですよね。