はじめに 🐢
墓に持っていく前に、自分の娘と息子と姪っ子達と一匹の亀のためにこれを書き残す。
JSの話です。
免責事項 🚑
・郷に入っては郷に従え。現場のスタイルに従いましょう。
・参考では薄めのオライリー本2冊のみ挙げました。
・クラスやアーキテクチャについては述べていません。
・元気です。肩は痛いです。
1.コメントは右端に 👉
コメントを新規行にて左端から書くと、コードと混在し可読性が下がる。
それを避けるために、コードの右端にコメントを書く。
その際、コメントの先頭位置を揃えるのではなく、末尾の位置を揃える1。
const arr = ['a', 'b', 'c']; // ここにコメントを書く
arr.reduce((a, v) => ({ ...a, [v]: v}), {}); // キーと値が同一のobj
2.短い方が良い 🐘
コードの量を減らすように努力する。
同一の処理内容では、コードの量が少ないほうが理解がしやすい2。
参考
・「余分なコードは決して書かない」『プログラマが知るべき 97 のこと』p.76
・「シンプルさは捨てることによって得られる」『プログラマが知るべき 97 のこと』p.144
2.1.変数名は短く
変数名は可能な限り短くする。
スコープが狭い変数は名前を短くできる3。
参考
3.波括弧を減らす 🌊
波括弧を減らし、ネストを避けると読みやすくなる。
変数への代入箇所を減らすことができる。
3.1.if を減らす
三項演算子や短絡評価(||, &&)で代用する4。
ifを減らすことにより、本当にifが必要な分岐を目立たせる事ができる。
3.2.for を減らす
map系で対応する。
4.再代入を避ける 🦏
const 一択5。
仕方なくletの場合は、宣言行と使用行を離さないように努める。
参考
5.スコープは狭く 🔍
変数も関数も、スコープは狭く。即時関数でスコープを狭める6。
即時関数の戻り値でconstに値を返すことにより、即時関数内の
変数や関数を閉じ込めることができる。
const hoge = (()=>{
const arr = ['a', 'b', 'c']; // arrをスコープ内に閉じ込めている
return arr.reduce((a, v) => ({ ...a, [v]: v}), {});
})();
参考
6.引数に関数を入れる 💉
ある関数の引数に関数を入れる7ことで、その関数(bar)に処理を外から挿入できる。
function bar(obj, fn){
Object.keys(obj).forEach(a => obj[a] = fn(obj[a]));
return obj; // 引数objの全要素に関数fnを適用し返す
}
bar({a: 1, b: 2}, x => x * x ); // {a: 1, b: 4}
ある処理ブロックを再利用したい場合、名前をつけて関数化して抜き出す。
その逆で、ある処理ブロック以外を再利用したい場合、即ちその部分を挿入したい場合は、上述のように引数に関数を入れるとうまく行く。
7.副作用を避ける 💊
純粋関数を目指す。
参考
8.無闇に関数にしない 🌙
被参照数1の処理ブロックは名前付きの関数にしない。
関数の多くは被参照が多であるが、これに被参照1のものが含まれると数が
多くなり、重要なものが埋もれてしまう。被参照数が2になった時に関数化する。
9.同じコードを書かない ✏️
原則書かない。
ただし 疎結合を優先 すること。
参考
・「DRY 原則」『プログラマが知るべき 97 のこと』p.58
10.コードを書くな。設計しろ 🎨
設計に時間を費やす8。コードは書かなければ書かないほど良い9。
参考
・「状態だけでなく「ふるまい」もカプセル化する」『プログラマが知るべき 97 のこと』p.62
・「単一責任原則」『プログラマが知るべき 97 のこと』p.146
・「関数の「サイズ」を小さくする」『プログラマが知るべき 97 のこと』p.178
・「ステートに注目する」『プログラマが知るべき 97 のこと』p.198
番外 🌀
- return は一つ(ガード節を除く)。
- フラグは使わない。
- 正規表現を使う。
- switchを使う10。
- 例外処理は最低限の範囲。
- インデントは411。
- 行の長さは80~100程度に収める。
- else を常に考慮する。
- finally を常に考慮する。
- strictモードを使う。
- 短絡評価は0に弱い12
- ド・モルガンの法則を使う13。
- 引数と戻り値を原則使う。
- if→ifはelse ifを検討する14。
ほか、参考図書内で読むべきもの📕
・「コードの論理的検証」『プログラマが知るべき 97 のこと』p.30
・「コードに書けないことのみをコメントにする」『プログラマが知るべき 97 のこと』p.34
・「ハードワークは報われない」『プログラマが知るべき 97 のこと』p.72
・「真実を語るはコードのみ」『プログラマが知るべき 97 のこと』p.120
・「コードは障害サポートするつもりで書く」『プログラマが知るべき 97 のこと』p.176
・「良いプログラマになるには」『プログラマが知るべき 97 のこと』p.182
脚注 🦶
-
内容や表現を工夫して字数を調整し、複数行であってもなるべく矩形になるように(でこぼこしないように)、読みやすいようにコメントを仕上げる。 ↩
-
理解が難しくなる場合は、コメントを書いて理解を助ける。 ↩
-
スコープが狭いのであれば、変数名は一文字や二文字(や三、四文字)で良い。狭いスコープが推奨されるため、結果的に変数名は短くなるはず。意味はコメントで補う。 ↩
-
理解が難しくなる場合は、コメントを書いて理解を助ける。 ↩
-
ブロックスコープは波括弧のみでも作れるが、値の返却には即時関数が必要。また、即時関数は引数も取れるため、即時関数で親スコープのどの変数を参照しているか明示することもできる。ほか })(); は波括弧閉じの記号に比べ特徴的であるため、即時関数でスコープを作っていることを強調することができる。 ↩
-
ここではコールバックという用語は用いない。広義と狭義の意味があるように思うが、語義は狭い方が良いため広義での利用は避ける。この指摘を参照。 ↩
-
設計書を作るのではなく、設計を行う。設計の成果物として、設計書が出力される。 ↩
-
バグが入り込む可能性を下げる事ができるため。 ↩
-
コールバック地獄はasyncで解消されたのだから2である必要はない。ネストが深いコードを書くこと自体がまずい(HTMLとCSSは例外かも)。2だと階層構造が見辛い。ifで4だと条件と内部の頭が揃う問題にはオールマンスタイルで対処。 ↩
-
例:0.01 || "x" ⇒ 0.01。0.00 || "x" ⇒ "x"。-0.01 || "x" ⇒ -0.01。外から来た値の数値変換と||を併せると、変換結果が0の時だけ想定外の挙動をする事になる。 ↩
-
論理積の否定は否定の論理和と等しく、論理和の否定は否定の論理積に等しい。条件でも集合でも役に立つ。参考1。参考2。 ↩
-
ifのネストは大抵何かおかしい。条件をまとめられないか検討する。ifが同一階層で並ぶ場合はelse ifを含め流れを見直す。 ↩