RIP

# はじめに 🐢
墓に持っていく前に、自分の娘と息子と姪っ子達と一匹の亀のためにこれを書き残す。
JSの話です。

<details><summary>免責事項 🚑</summary><div>
・JSのベストプラクティスではありません。私見です。<br>
・郷に入っては郷に従え。現場のスタイルに従いましょう。<br>
・参考では薄めのオライリー本２冊のみ挙げました。<br>
・クラスやアーキテクチャについては述べていません。<br>
・元気です。肩は痛いです。
</div></details>

# １．コメントは右端に 👉
コメントを新規行にて左端から書くと、コードと混在し可読性が下がる。
それを避けるために、コードの右端にコメントを書く。
その際、コメントの先頭位置を揃えるのではなく、末尾の位置を揃える[^1]。
```js
const arr = ['a', 'b', 'c'];                  // ここにコメントを書く
arr.reduce((a, v) => ({ ...a, [v]: v}), {});  // キーと値が同一のobj
```

# ２．短い方が良い 🐘
コードの量を減らすように努力する。
同一の処理内容では、コードの量が少ないほうが理解がしやすい[^2]。
<details><summary>参考</summary><div>
・「13章 短いコードを書く」『リーダブルコード』p.167<br>
・「余分なコードは決して書かない」『プログラマが知るべき 97 のこと』p.76<br>
・「シンプルさは捨てることによって得られる」『プログラマが知るべき 97 のこと』p.144<br>
</div></details>


### ２．１．変数名は短く
変数名は可能な限り短くする。
スコープが狭い変数は名前を短くできる[^3]。
<details><summary>参考</summary><div>
・「スコープが小さければ短い名前でもいい」『リーダブルコード』p.23<br>
</div></details>



# ３．波括弧を減らす 🌊
波括弧を減らし、ネストを避けると読みやすくなる。
変数への代入箇所を減らすことができる。

### ３．１．if を減らす
三項演算子や短絡評価（||, &&）で代用する[^4]。
ifを減らすことにより、本当にifが必要な分岐を目立たせる事ができる。

### ３．２．for を減らす
map系で対応する。

# ４．再代入を避ける 🦏
const 一択[^5]。
仕方なくletの場合は、宣言行と使用行を離さないように努める。
<details><summary>参考</summary><div>
・「変数は一度だけ書き込む」『リーダブルコード』p.123<br>
</div></details>

# ５．スコープは狭く 🔍
変数も関数も、スコープは狭く。即時関数でスコープを狭める[^6]。


即時関数の戻り値でconstに値を返すことにより、即時関数内の
変数や関数を閉じ込めることができる。
```js
const hoge = (()=>{
    const arr = ['a', 'b', 'c'];    // arrをスコープ内に閉じ込めている
    return arr.reduce((a, v) => ({ ...a, [v]: v}), {});
})();
```
<details><summary>参考</summary><div>
・「JavaScriptで「プライベート」変数を作る」『リーダブルコード』p.117<br>
</div></details>

# ６．引数に関数を入れる 💉
ある関数の引数に関数を入れる[^7]ことで、その関数（bar）に処理を外から挿入できる。
```js
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}
```
::: note info
ある処理ブロックを再利用したい場合、名前をつけて関数化して抜き出す。
その逆で、ある処理ブロック以外を再利用したい場合、即ちその部分を挿入したい場合は、上述のように引数に関数を入れるとうまく行く。
:::

# ７．副作用を避ける 💊
純粋関数を目指す。
<details><summary>参考</summary><div>
・「関数型プログラミングを学ぶことの重要性」『プログラマが知るべき 97 のこと』p.4<br>
</div></details>

# ８．無闇に関数にしない 🌙
被参照数１の処理ブロックは名前付きの関数にしない。

関数の多くは被参照が多であるが、これに被参照１のものが含まれると数が
多くなり、重要なものが埋もれてしまう。被参照数が２になった時に関数化する。


# ９．同じコードを書かない ✏️
原則書かない。
ただし [疎結合を優先](https://www.infoq.com/jp/news/2012/05/DRY-code-duplication-coupling/) すること。
<details><summary>参考</summary><div>
・「共有は慎重に」『プログラマが知るべき 97 のこと』p.14<br>
・「DRY 原則」『プログラマが知るべき 97 のこと』p.58<br>
</div></details>

# 10．コードを書くな。設計しろ 🎨
設計に時間を費やす[^8]。コードは書かなければ書かないほど良い[^9]。
<details><summary>参考</summary><div>
・「美はシンプルさに宿る」『プログラマが知るべき 97 のこと』p.10<br>
・「状態だけでなく「ふるまい」もカプセル化する」『プログラマが知るべき 97 のこと』p.62<br>
・「単一責任原則」『プログラマが知るべき 97 のこと』p.146<br>
・「関数の「サイズ」を小さくする」『プログラマが知るべき 97 のこと』p.178<br>
・「ステートに注目する」『プログラマが知るべき 97 のこと』p.198<br>
</div></details>


# 番外 🌀
1. return は一つ（ガード節を除く）。
1. フラグは使わない。
1. 正規表現を使う。
1. switchを使う[^10]。
1. 例外処理は最低限の範囲。
1. インデントは４[^11]。
1. 行の長さは80～100程度に収める。
1. else を常に考慮する。
1. finally を常に考慮する。
1. strictモードを使う。
1. 短絡評価は０に弱い[^12]
1. [ド・モルガンの法則](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%BB%E3%83%A2%E3%83%AB%E3%82%AC%E3%83%B3%E3%81%AE%E6%B3%95%E5%89%87)を使う[^13]。
1. 引数と戻り値を原則使う。
1. if→ifはelse ifを検討する[^14]。

<details><summary>ほか、参考図書内で読むべきもの📕</summary><div>
・「リファクタリングの際に注意すべきこと」『プログラマが知るべき 97 のこと』p.12<br>
・「コードの論理的検証」『プログラマが知るべき 97 のこと』p.30<br>
・「コードに書けないことのみをコメントにする」『プログラマが知るべき 97 のこと』p.34<br>
・「ハードワークは報われない」『プログラマが知るべき 97 のこと』p.72<br>
・「真実を語るはコードのみ」『プログラマが知るべき 97 のこと』p.120<br>
・「コードは障害サポートするつもりで書く」『プログラマが知るべき 97 のこと』p.176<br>
・「良いプログラマになるには」『プログラマが知るべき 97 のこと』p.182<br>
</div></details>

# 脚注 🦶

[^1]:内容や表現を工夫して字数を調整し、複数行であってもなるべく矩形になるように（でこぼこしないように）、読みやすいようにコメントを仕上げる。
[^2]:理解が難しくなる場合は、コメントを書いて理解を助ける。
[^3]:スコープが狭いのであれば、変数名は一文字や二文字（や三、四文字）で良い。狭いスコープが推奨されるため、結果的に変数名は短くなるはず。意味はコメントで補う。
[^4]: 理解が難しくなる場合は、コメントを書いて理解を助ける。
[^5]: [巻き上げ](https://qiita.com/jkr_2255/items/9f9a25987dfaa81472fa)とスコープの問題があるのでvarは禁止。
[^6]: ブロックスコープは波括弧のみでも作れるが、値の返却には即時関数が必要。また、即時関数は引数も取れるため、即時関数で親スコープのどの変数を参照しているか明示することもできる。ほか })(); は波括弧閉じの記号に比べ特徴的であるため、即時関数でスコープを作っていることを強調することができる。
[^7]: ここではコールバックという用語は用いない。広義と狭義の意味があるように思うが、語義は狭い方が良いため広義での利用は避ける。[この指摘](https://stackoverflow.com/a/33023472)を参照。
[^8]: 設計書を作るのではなく、設計を行う。設計の成果物として、設計書が出力される。
[^9]: バグが入り込む可能性を下げる事ができるため。
[^10]: [正規表現でもswitchは可能](https://kuroeveryday.blogspot.com/2015/07/Match-Switch.html)。
[^11]: コールバック地獄はasyncで解消されたのだから２である必要はない。ネストが深いコードを書くこと自体がまずい（HTMLとCSSは例外かも）。２だと階層構造が見辛い。ifで４だと条件と内部の頭が揃う問題には[オールマンスタイル](https://ja.wikipedia.org/wiki/%E5%AD%97%E4%B8%8B%E3%81%92%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB#BSD/%E3%82%AA%E3%83%BC%E3%83%AB%E3%83%9E%E3%83%B3%E3%81%AE%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB)で対処。
[^12]: 例：0.01 || "x" ⇒ 0.01。0.00 || "x" ⇒ "x"。-0.01 || "x" ⇒ -0.01。外から来た値の数値変換と||を併せると、変換結果が0の時だけ想定外の挙動をする事になる。
[^13]: [論理積の否定は否定の論理和と等しく、論理和の否定は否定の論理積に等しい](http://www.crl.nitech.ac.jp/~ida/education/MaterialsDesign/1120.html)。条件でも集合でも役に立つ。[参考1](https://xtech.nikkei.com/it/article/Watcher/20070806/279127/)。[参考2](https://qiita.com/tanaka-qtaro/items/f31608db855672cdbb6f)。
[^14]: ifのネストは大抵何かおかしい。条件をまとめられないか検討する。ifが同一階層で並ぶ場合はelse ifを含め流れを見直す。