jsの命名ルールについて考えてみる

# はじめに
jsを書いていると、変数や関数の命名に悩まされることがよくあります。
自分では適切な名前をつけているつもりでも、第三者には正確には伝わっていなかったり、似たような命名が複数出てしまうことで、コードの可読性が低くなってしまったり…。

コードのリファクタリングについて相談した時に、よくエンジニアの人に勧められる本で「リーダブルコード」というものがあります。本書内で優れたコードの定義として下記が挙げられています。

✅ コードは理解しやすくなければならない。
✅ コードは他の人が最短時間で理解できるように書かなければならない。
✅ コードは短くしたほうがいい。だけど「理解するまでにかかる時間」を短くするほうが大切。

いずれも「理解しやすいコード」という部分を重要視してます。
理解しやすいコードを構成する1つの要素として、「適切な名前の選び方」ということが含まれます。
本記事では、jsの命名について考えてみたいと思います。

# 命名ルールを決めてみよう！
「理解しやすいコード」を目指した時に、命名である程度の意味や使用用途を推測できるように、いくつかルールを決めてみましょう。まずはjsの機能別に記法を定義し、何が記述してあるのかわかりやすくしてみます。

## 変数・関数など基本のコード
ローワーキャメルで記載します。`currentUserItem`のように、先頭は小文字、先頭以外の最初は、大文字で書き始めます。

```js
const alertMessage = '入力した内容に誤りがあります。';
const displayAlert = () => {
    alert(alertMssage);
}
```

## 定数名
ここでの定数とは、constで宣言した再宣言できない変数のことではなく、常に同じ値が入る固定のものです。スネークケースで記載します。`CURRENT_USER_ITEM`のように、大文字をアンダースコアで連結して記述します。下記の例は、商品割引を適用するためのクーポンコードを変数に入れた時の例です。クーポンコードは変更されることはないので、定数として扱います。

```js
const COUPON_CODE300 = discount_code_300;
```

## クラス名
クラス名はアッパーキャメルケース（パスカルケース）で記載します。 アッパーキャメルケースとは、SalesPersonのように先頭が大文字でその後につなげる単語の頭文字を大文字にする記法です。

```js
class SampleUser {
    constructor( name, age ) {
        this.name = name;
        this.age = age;
    }
}
```

# わかりやすい命名を意識しよう
命名である程度を推測できるようにするためには、「誤解されない名前をつける」「名前に情報を詰め込む」ことが大切になってきます。適切な命名について、例を挙げていきたいと思います。

## 名前は省略しすぎない
一文字の変数や一般的ではない略語は、コードを読む上で混乱を招きます。
また、複数の意味が推測されるような省略は、適切ではありません。
省略する場合は、意味がわかる程度に抑えましょう。

```js
// 省略しすぎ
const e = '購入処理がうまくできませんでした' //=> × 
const erms = '購入処理がうまくできませんでした' //=> × 

// 意味がわかる程度の省略
const errMsg = '購入処理がうまくできませんでした' //=> ◯ 
const errorMessage = '購入処理がうまくできませんでした' //=> ◯

// nmが'name'と'number'の2つの意味が推測されてしまう
const result = nm01 + nm02; //=> × 

// 誤解されない程度の省略
const result = name01 + name02; //=> ◯ 
const result = num01 + num02; //=> ◯
const result = number01 + number02; //=> ◯
```

## 適切な名前をつける
例えばポップアップを実装した時に、閉じるボタンと背景をクリックすると、ポップアップが非表示になる仕様だったとします。その場合、2つの要素を`closeBtn`と定義せずに、適切な名前をつけましょう。

```js
// 適切ではない名前（背景はボタンではない）
const closeBtn = document.querySelectorAll('.popup_btn_close, .popup_bg'); //=> × 

// 2つの要素に対して、適切な名前
const closeElement = document.querySelectorAll('.popup_btn_close, .popup_bg'); //=> ◯ 
```

## 名前から処理内容がわかるようにする
機能名だけではなく、名前に動詞をプラスすることによって、どのような処理をするコードなのか、分かりやすくしましょう。

```js
// ポップアップをどうする関数を実行しているのかわからない
popup(); //=> × 

// 動詞を入れることで、ポップアップの処理内容が想像できる
displayPopup(); //=> ◯

// 動詞を過去形にすることで、選択された状態と表すことができる
selectedName(); //=> ◯
```
# 命名規則に使える英単語一覧
迷った時にあると便利な命名規則を集めてみました。

## 状態に関する命名
| 単語   |     意味      | 例 |
| --- | ----------- | ------- |
| is    | 〜になっているか |      isShow |
| can    | 〜できるか |      canRemove |
| should    | 〜するべきか |     shouldMigrate |
| has    | 〜を持っているか |   hasProperty |

## 追加に関する命名
| 単語   |     意味      | 例 |
| --- | ----------- | ------- |
| set    | 〜を設定する |      setAccount |
| add    | 〜を追加する |      addList |
| insert    | 〜を挿入する |     insertText |
| append    | 〜を末尾に追加する |   appendHtml |

## 削除に関する命名
| 単語   |     意味      | 例 |
| --- | ----------- | ------- |
| delete    | 〜を削除する（復元不可） |      deleteAccount |
| remove    | 〜を除去する（復元可）  |      removeAccount |
| reset    | 〜を初期化する |     resetData |
| unregister    | 〜（登録済のデータ）を解除する |   unregisterMember |

## 順序や関係性に関する命名
| 単語   |     意味      | 例 |
| --- | ----------- | ------- |
| current    | 現在の |      currentPage |
| previous    | 前回の  |      previousPage |
| next    | 次回の |     nextPage |
| before    | 〜の前に |   insertBefore |
| after    | 〜の後に |     insertAfter |
| latest    | 最新の |     latestEntry |
| last    | 最後の |     lastEntry |
| first    | 最初の |     firstEntry |
| parent    | 親要素 |     parentElement |
| child    | 子要素 | childElement |

# さいごに
いかがでしたでしょうか？
普段何気なくつけている命名ですが、「コードを深く読み込まなくても、ある程度のことが理解できる」命名規則を意識すると、自分で判断するのはなかなか難しいですね。
いろいろな人にコードを見てもらい、レビューをもらうことがとても大切だと思いました。
読みやすいコードを目指した時の最初の取っ掛かりとして、命名を意識していきたいと思います。