クリーンコード

# クリーンコードの原則
* 他人が読みやすい
* コードの意味がわかりやすく、文章のように意味が伝わる。
* 読んでいて疲れない
* 変数、関数、クラス名が適切な名前
* 無駄な部分まで読む必要がない
* バグが混入しにくい
* 改修箇所が限定される
* 改修による既存コードへの影響が限定される
* 新規機能を追加しやすい
* 冗長な記述がない
* テストがしやすい
* コードの流れに一連の文脈が存在する

# 命名規則
```
# bad
const a = 300 / 60;

# good
const mintutes = 300;
const hours = minutes /60;
```

```
# bad
function calc(number) {
  return number / 60;
}

# good
function convertMinutesToHours(minutes) {
  return minutes / 60;
}
```
## 良い変数名
* 変数が保持するものを正確に説明
* 曖昧でなく明確に説明
* 短すぎず、長すぎないように
* 多くに人に意味がわかる
* 発音可能

## 識別子とケース
識別子：変数名、関数名、クラス名などの識別するためのもの

* ケバブケース
kebabu-case
* スネークケース
snake_case
* アッパースネークケース（コンスタントケース）
UPPER_SNAKE_CASE
* パスカルケース
PascalCase
* キャメルケース
camelCase


## 審議値の変数名
* is〜
isEmpty, isSet
* 過去分詞系
done, finished, sent, put

## 変数名の接頭語
* get〜：値を返す、取得する
`getInteger`
* set〜：値を設定する
`setName`
* is〜：真偽値を返す
`isEmpty`
* has〜：持っているか
`hasPosts`
* needs〜：必要か
* can:〜できるか
`canStartTime`
* should：〜すべきか

** isExistsなど動詞が連続するような命名は避けて、Existsなど三人称をつける対応。
https://qiita.com/yskszk/items/5a7f99c974773f03a82a

## 変数名、プロパティ：（形容詞＋）名詞
* themeColor
* customerType
* serviceName

## 関数、メソッド：動詞（＋形容詞＋名詞）
* getNumbers
* getUserName
* addActiveButton

## クラス：（形容詞＋）名詞
* Animals
* ScoreCounter
* PurchaseHistory


## 配列の末尾には複数名のsをつける
```
# bad
user.forEach
#good
users.forEach

# bad
animal.map
animals.map
```

## ウソの変数名をつけない
```
# bad
# 配列ではなく、オブジェクトであり、リストでもないので誤った印象を与える。Listは配列の印象を与える。
const averageList = {
  japanese: 30,
  math: 10,
  English: 30
}

# good
const AVERAGE_SCORE = {
  japanese: 30,
  math: 10,
  English: 30
}
```

`AVERAGE_SCORE.japanese`のように参照するので、その辺りも意識すると良い。値の保持ならキャメルケースでも良いかも。ただ、constであってもオブジェクトのプロパティは更新可能なので、定数化しても良いかもしれない。


## 同じ意味合いの単語は統一すること
以下は類似単語の例
```
start, begin
stop, end
modify, update, change
create, new, factory
find, search
done, finish, complete
deliver, dispatch, send
select, choose
show, display
```

## 反対の意味を持つ値は対比の名前をつける
```
prev/next
first/last
create/delete
source/destination
add/remove
show/hide
min/max
public/private
success/failure
```


## 意味のない単語を含めない
`String`いらない
`personNameString`

`Data`や`Info`はなくてもいい。
`UserData`や`UserInfo`

あと個人的に気になるのが、
`usersList`のように複数形にListをつける形。`users`だけで十分意味は伝わるので`List`は不要。

## 変数名を省略するコツ
a11y: accessibility
i18n: internationalization
init: initialize
calc: calculation
idx: index
cstm: customer
srvc: service
btn: button
_privateMethod, _privateProp（最近は#で表すようになった。）

# 関数定義
* 関数は責務を小さく作る
* 関数内でなるべく条件分岐をかかない
* 関数はDRYで作成使用
たまたま共通しているからといって共通しないように、ドメインを意識できると良い。


## 引数が多いとオブジェクトにまとめる
目安は引数が3以上？
```
function storeUser(user){
// userの保存処理
}

const user = {
userId: 1,
name: "Tom",
age: 22,
hobby: "soccer",
};

storeUser(user);
```

## 引数の設定では論理和よりデフォルト引数を使う
以下は初級者は結構見逃しがちかも。
```
論理和では`falsy`かどうかが判断基準
引数のデフォルト値は`undefined`かどうかが判断基準
```

例えば、falsyである`0`を使うと、
論理和の場合はfalsyとなり、100が設定されてしまう。
一方でデフォルト引数の場合は想定通り0を設定できる。

レアケースかもしれないが、一応頭の片隅には押さえておきたい。
```
function drawSquare(color, size ){
size = size || 100;
  render('square', size, color);
}

# 0にすると想定通りにならず、100がセットされる。
draqSquare('#fff', 0)
```

以下のようにデフォルト引数を使用すると`undefined`のみセットされるので想定通りとなる。
```
function drawSquare(color, size = 100 ){
size = size || 100;
  render('square', size, color);
}

drawSquare('#fff')
draqSquare('#fff', 0)
```

# オブジェクトを引数で渡す
これはよく考えると使ったことなかったなー。
```
function createUser ({age = -1, name= "no name", posts = []} = {} ) => {
  const registerUser = {age, name, posts};
  db.user.create(registerUser);
}
```


## 関数は使用順に上から下に書く（垂直フォーマット）
## 参照透過性
決まった入力（引数）に対して、必ず決まった出力を返す
## 副作用のない関数を分離することでテストをしやすくなる
## 渡ってきたオブジェクトの中身を書き換えるのは止める
以下のように引数を変えて返すような記述はだめ。
```
function sortDesc(itemIds){
  itemIds.sort();
}
const itemIds = [4, 3, 2, 1]
sortDesc(itemIds);
```
新しい変数を用意してそれに格納する。
```
function sortDesc(itemIds){
  const newItemIds = [...itemIds]
  newItemIds.sort();
  return newItemIds
}
const itemIds = [4, 3, 2, 1]
const sortedItemIds = sortDesc(itemIds);
```

#　クラス
* クラスはなるべく小さく作る
```
class Cart {
  addProduct(){}
  addProductPrice(){}
  addProductCoupon(){}
  calculatePrice(){}
  printReceipt(){}
}
```
```
class Product {
  getPrice(){}
  getCoupon(){}
}

class Cart {
  add(){}
  calculatePrice(){}
  printReceipt(){}
}
```

## クラスの情報はできる限り隠蔽する
意図しない変更を避けるためにクラス情報はできる限り隠蔽する。

以下の書き方だと外部から呼び出し可能。
``` class Television {
  modelNumber = '型番'
　　 # 以下の書き方でもok.引数を取る場合はconstructorを使うこと。
　　 constructor(){
    this.modelNumber = '型番'
   }
}
```

## 外部からの呼び出しを避けるために、変数の前に`#`をつける。
``` class Television {
  # 以下のように書くとインスタンスを生成しても
  # console.log(television.#modelNumber)のように呼び出せない。
　　 # #を使う場合、constructorで初期化する場合にも`#hoge`で冒頭で宣言する必要あり。
  #modelNumber = '型番'

  # ただし、クラス内の関数で呼ばれているものについては、外部からでも参照可能。
  displayModelNumber(){
    console.log(television.#modelNumber)
  }

　　　　# 変更や取得もクラス内にメソッドを定義して可能。
　　　　get modelNumber() {
    return this.#modelNumber;
  }

　　　　set modelNumber(modelNumber) {
    this.#modelNumber = modelNumber
  }
}

  #　この取得や変更のセッター、ゲッターの場合、以下のような書き方ができる。
  console.log(television.modelNumber) #　ゲッター 
  television.modelNumber = '12345' #　セッター
```