◆ JavaScript の書き方のルール
◆ 全部好きってわけじゃないけどけっこう好みにあってる

たまたま github でみかけたプロジェクトにこんなアイコンがついてました



なにこれ?と思ってググってみると JavaScript のコーディングのスタイルみたいです

JavaScript Standard Style という名前ですが これが JavaScript の公式なスタイルというわけではなくていろいろあるコーディングルールのひとつです
ですが github Star が 7000 以上で 最近月間ダウンロードが 187k (18万) もあるのでけっこう有名みたいです

できたのが去年の 2015 年で今でも頻繁にアップデートされています
アップデートといってもルールが変わるのじゃなく ルールに沿って書くための lint や formatter などのツールをアップデートしてるようです


今回はこの JavaScript Standard Style のルールを紹介+個人的な感想を書いていこうと思います

JavaScript Standard Style


Rules にルールの一覧が書かれています
サンプルコードはそのままの引用多めです

インデントはスペース2 つ

function hello (name) {
  console.log('hi', name)
}

タブはダメみたいです
function badhello(name){
console.log('hi', name)
}


スペースインデント嫌いなのでこれは無視したいところ……

devtools のコンソールなどタブがかけないときは スペース 2 つなので書く分にはそこまで困らないですが ある程度の規模なコードを読むときに インデントの差が小さいと見づらいんですよね

基本はシングルクオートを使う

console.log('hello there')
$("<div class='box'>")


これも個人的には 「"」 を基本の文字列にしたいのでやめてほしいところ
C 系のように 「"」 が文字列で 「'」 が文字っていう言語は見ますが 反対は見たことがないので 「"」 を文字列中で使いたい時だけ 「'」 を使うようにしたいです

また これは日本語圏の人だけですが 日本語キーボードだと「'」は数字の「7」をシフトキーと一緒に押します
「"」 は数字の「2」をシフトキーと一緒に押します
キーボードの位置的に「7」を打つには右腕自体を動かないと届かないですが 「2」 は左手の指を伸ばせばなんとか届きます
人によりますが頻繁に入力する文字列の囲みを 「'」にするのは抵抗(物理的な)が大きいです

このルールを使うとしても 自分で書くときは 「"」 で自動フォーマットで修正してもらう になるでしょうねー

使ってない変数は定義しない

function f(){
  var a = 1 // ←
  var b // ←
  var c = false
  return c
}


普通は使わないものをあえて定義することはないと思いますが コードを色々変更したときに使わなくなったのを消し忘れるということはけっこうあると思うので そういうのをなくそう ということですね

キーワードのあとはスペース入れる

if (condition) { ... }
if(condition) { ... }


if とか for などの後にスペースがいるそうです
上の使っていない変数を定義しないなどと違い どうでもいいところです
インデントとも違い ここにスペースがあろうがなかろうが困ることもないです
ルール考えた人の好みでしょうし 書くときは好きに書いて自動フォーマットにやらせればいいと思います
わざわざ毎回スペース入力って意外とめんどうですから

関数定義のカッコの前にスペース入れる

function name (arg) { ... }
fun(function () { ... })
function name(arg) { ... }
run(function() { ... })


これもどうでもいいところなので自動フォーマット任せで

私が普段書くときは
function name(){}
run(function(){})

でいらないところにスペースをわざわざ入れないですが 入れたがる人が多いのはどうしてなのかなー
なくても見づらいことはないのにムダなことしたくないですよ

=== 使う

比較には === を使います
== は null か undefiined にマッチさせたいときの例外を除いて使いません
if (name === 'John')
if (name !== 'John')
if (name == 'John')
if (name != 'John')


これは納得です
null と undefined を一緒に扱いたい例外時だけ == 許可するというのも私の使い方と一緒です

2 項演算子は間にスペースが必要

+ とか = などの前後に式がある演算子の前後にはスペースを入れます
var x = 2
var message = 'hello, ' + name + '!'
var x=2
var message = 'hello, '+name+'!'


これもどっちでもいい部分ですが if や 関数名の後のスペースと違い あったほうが見やすい場合も多いので私も入れてることが多いです
でも for だと入れないことも多いです
for(var i=0;i<10;i++){
}

カンマの後にはスペースを入れる

var list = [1, 2, 3, 4]
function greet (name, options) { ... }
var list = [1,2,3,4]
function greet (name,options) { ... }


これもどっちでもいいけど あったほうが見やすいこともある ってところでしょうか
ただ
[1,2,3,4]
程度ならなくても見づらくはないのでどっちでもいいですが
[false,true,a + b,(x ? y : z),func(1 + 2),'str','str2']
こんなになってくるとスペース入れたくなりますね

else は if の閉じカッコと同じ行に書く

if (condition) {
  // ...
} else {
  // ...
}
if (condition) {
  // ...
}
else {
  // ...
}


こんな特殊なことは普通しないと思います
それより if や function や return などの 「{」 を同じ行に書くって制限を入れた方がいいと思います
VisualStudio のデフォルトみたいに次の行に書く癖があると return でもやってしまってバグが!ってこともありえます

if を複数行にするときはカッコが必要

if (options.quiet !== true) console.log('done')
if (options.quiet !== true) {
  console.log('done')
}
if (options.quiet !== true)
  console.log('done')


これは私も思います
2行で書いて カッコないのは気持ちわるすぎですし 後から修正するときにも負担になります

ただ if とだけ書いてますが for や while や do にもですよね……?

err パラメータは絶対に処理する

run(function (err) {
  if (err) throw err
  window.alert('done')
})
run(function (err) {
  window.alert('done')
})


めんどうでも無視せず throw しましょうってことみたいです
昔は非同期だと throw しても try catch で取れなかったのですが Promise など throw すれば受け取れますからね

グローバル変数には window をつける

window.alert('hi')

document, console, navigator は例外です


自作のグローバル変数の定義や参照 あと window.onload などプロパティとして使っているものには window つけるべきだと思っていますが alert みたいなただの関数にまで付ける必要はあるのかなーと思います

2行以上の空行を作らない

var value = 'hello world'
console.log(value)
var value = 'hello world'


console.log(value)


基本的には2行以上の空行はいらないと思うのですが ときどき 2行空行でここからはちょっと別系なものが多いから区切り としてたりもするので 「避ける」ではなく「禁止」とルールにしてしまうのはどうなんだろうとも思います

? : 演算子を複数行にするときは ? : から書き始める

var location = env.development ? 'localhost' : 'www.api.com'

var location = env.development
  ? 'localhost'
  : 'www.api.com'
var location = env.development ?
  'localhost' :
  'www.api.com'


行末に書くか 行頭に書くかでよく迷うのですが 最後だけ行末に何もないのはなんとなく気持ち悪いですし 行頭にあるほうが揃っていて綺麗なのでこれにしようかなと思います

var はひとつずつ書く

カンマ区切りは使いません
var silent = true
var verbose = true
var silent = true, verbose = true

var silent = true,
    verbose = true


これはすごく賛成です
var 一個だけかいてるコードは 見づらいですし 修正するときにも手間です
カンマのミスとか出てきますし
単純に1行の追加・削除で終わらせられるスタイルがいいですよね

昔 というか C 系のコード書いてる人のコードだと var ひとつで全部最初に定義してしまうのが多かったように思います
ですが 最近で JavaScript メインに書いてそうな人のコードを見ていると ひとつの var でまとめて書いてるっていうのはそんなに見ない気がします
var ひとまとめのほとんどは 一部の昔からあるライブラリや minify 後のコードで そういうのは読むときに見づらいなぁって感じてます

条件式中の代入は追加で () で囲む

if とか while の条件を書くところで代入 (=) を使う場合は余分に () で囲みます
while ((m = text.match(expr))) {
  // ...
}
while (m = text.match(expr)) {
  // ...
}


ぱっと見てなにこれ と思いますが ミスじゃなくてわざと代入してますよー ってわかりやすく宣言してることになるのでありな気がします
代入したものを比較したくなったときにも
while ((m = f()) !== false) {
  // ...
}

という風に なるので () をその場で追加しなくて済みます
演算子の優先順どっちだったかなーと考えなくていいですし間違わずにも済みます
a = b === c
だと 比較結果を代入してしまい 代入後に比較にはなりません

ただ == じゃなくて === を使うなら = と === なので入力ミスなんてそうそうないよね とも思いますけどね

セミコロンはつけない

window.alert('hi')
window.alert('hi');

セミコロンなしで問題が起きないように 「(」 と 「[」 と 「`」 から行を始めない
;(function () {
  window.alert('ok')
}())

;[1, 2, 3].forEach(bar)

;`hello`.indexOf('o')
(function () {
  window.alert('ok')
}())

[1, 2, 3].forEach(bar)

`hello`.indexOf('o')



ノー!!セミ!!!コロン!!!!!

いいですね
素晴らしいですね

セミコロンを書きましょうなんてルールなら紹介なんてしなかったですよ
これまで 文字列は「'」とか嫌なルールもありましたが セミコロンなしはそれらを覆すくらいに重要ですよ

未だにセミコロン書きたがる人が多いですからね
このルールを機にセミコロンなしが主流になってほしいですね


アドバイスで
;[1, 2, 3].forEach(bar)
と書くなら
var nums = [1, 2, 3]
nums.forEach(bar)
こう書いたほうがいいよというのがありました

nums のところにその数字が何を表してるか名前つけたほうが見やすいっていうのは一理あります
何でもかんでも短くし過ぎない ほどほどにというところでしょうかね

短くしたいけど 「;」 から始めるのも減らしたいって時はこういう方法もあります

配列の場合
Array.of(1,2,3).forEach(bar)

無名関数の即時実行の場合
!function () {
  //
}()
返り値を使うなら boolean キャストする 「!」 使っちゃだめですが 返り値を使う場合は 行が 「(」 から始まることはないはずなので 「(」 から始まる場合は 「!」 にしてしまって大丈夫でしょう
返り値からメソッドチェーンする場合は 「(」 から始まりますが 最終的に代入されないなら 「!」から始めても大丈夫です


その他の 「(」 から始まる場合は一度代入したほうがケースが多いと思います
;("0" + num).substr(-3).split("").forEach(bar)
みたいなの


あとここでは触れられていないですが正規表現リテラルの 「/」 も行頭に来るときは 「;」 書いたほうがいいです
割り算扱いされてしまうケースがあります



セミコロン書かない理由の一つで上げられていた youtube の動画ではセミコロン書くスタイルのほうがどこにかけばいいのか混乱することになる と言われていました
function bear () {
  return {
    type: 'grizzly'
  };
}

var bear = function () {
  return {
    type: 'grizzly'
  };
};

class Bear {
  growl () {
    return 'grr';
  }
}

if (isbear) {
  //
}

while (stillabear) {
  //
}

確かにセミコロンどこに入れるか意外と難しいですね
実際にセミコロン入れてる人のコード見ていても 必要なところで入っていないのがあったり いらないところにつけたりするのが多いです
関数定義でも宣言ならいらなくて無名関数代入なら 代入文なので必要 と複雑です

実際セミコロンなくても動くので 困ってはいないのでしょうが セミコロンを書くなら正確に書くべきですし もしセミコロンないとシンタックスエラーだとすれば動かないような中途半端なコードにするなら最初からセミコロン無しのほうが気持ちが良いものです

これまでは面倒なもの書きたくないってだけでしたが 「書くほうが難しい」 これも十分な理由ですね

まとめ

これまで知らなかったですが 意外と人気だったコーディングスタイルの紹介でした

スペース入れるとか個人の好みであって ルールにまでする必要ないものがちょっと多めだった気がします
ルールにするなら === をつかうとか セミコロンは書かないとか var は一行ずつとかコード的に意味があってバグが減るとか修正しやすいなどのメリットがあるものだけでいいんじゃないかなー と思います

一応自動フォーマットしてくれるみたいなので それのためと考えれば 仕方ないのかも
スペースあってもなくても見る分には影響ないですからね

でもインデントスペースだけは 見づらいのとコード修正時に 1 インデント単位でカーソル動かせないのがちょっと不便

セミコロン書きたい人向けな別バージョン semistandard もあるんだしタブバージョンもあったらなー と思ってみたり