こんにちは、sanagiです。
皆さんは、普段コードを書く際どんなことに気を付けて書いてますか?
今回は、保守性の高いコードを目指そうをテーマにlet/constをテーマにブログを書いてみようと思います。
JavaScriptの変数宣言(var, let, const)について
まず、JavaScriptで変数宣言する方法をについて説明します。もう既に知っているよ!という方は飛ばしてください。
JavaScriptで変数宣言する方法は3つあります。var, let, constの3つです。以下解説します。
① var
varは現在公式でも非推奨とされていますが、varで変数を宣言すると、再代入・再宣言が可能になります。そのため、以下のような変数宣言が可能になります。
var name = 'aaa';
〇 name = 'ccc'; // 再代入可能
〇 var name = 'bbb'; // 再宣言可能
② let
letは再代入可能、再宣言不可になります。以下のようなイメージですね。
let name = 'aaa';
〇 name = 'ccc'; // 再代入可能
× let name = 'bbb'; // 再宣言不可
③ const
constは参照のみ許可とされており、再代入も再宣言も不可とされています。
const name = 'aaa';
× name = 'ccc'; // 再代入不可
× let name = 'bbb'; // 再宣言不可
varとletはなぜ保守性が良くないのか?
なぜ、varやletは保守性が良くないとされるのか?
それは、再代入が可能になっているからです。
再代入が可能になっていると、ソースを追うときに読み手が、変数がどこで上書きされるのか、注意して読まないといけなくなるからです。
例えば、こんな感じでグローバル変数のように値が書き換えられてしまう可能性があるので、「name」でソース内検索をかけてどこで書き換えられているのか全体的に調べる必要が出てきます。
let name = '花子';
const updateName = () => {
if (isBoy) {
name = '太郎';
}
}
constであれば変数が定義されている箇所のみを確認すれば良いので、一般的にはできるだけconstを使うのが良いとされています。
letをconstで定義する方法①(三項演算子)
ここまでconstを使う理由について書いてきましたが、そしたらどうやってletを使わずに書いたら良いのか?
以降はその方法について解説していきます。
まず1つ目は三項演算子です。三項演算子とは以下のように表現する書き方のことです。
条件式 ? true時の処理 : false時の処理;
例えば、先ほど説明で使用した以下のソースは、
let name = '花子';
const updateName = () => {
if (isBoy) {
name = '太郎';
}
}
このように書くことができます。
const name = isBoy ? '太郎' : '花子';
これで1つlet定義を減らすことができましたね。
letをconstで定義する方法②(関数化)
2つ目は、シンプルに「関数化してしまう」です。
三項演算子は便利ですっきり書けますが、処理の分岐が多かったり、処理内容が長くなる場合は、三項演算子で書くと可読性が悪くなってしまいますよね。。
その場合は、関数化してしまいましょう。
例えば以下のような分岐が少し多い場合、
let japaneseFruit;
switch (tgtFruit) {
case 'strawberry':
japaneseFruit = 'いちご';
break;
case 'melon':
japaneseFruit = 'メロン';
break;
case 'apple':
japaneseFruit = 'りんご';
break;
default:
japaneseFruit = '';
}
以下のように関数化することができます。
const getJapaneseFruit = () => {
switch (tgtFruit) {
case 'strawberry':
return 'いちご';
case 'melon':
return 'メロン';
case 'apple':
return 'りんご';
default:
return '';
}
}
const japaneseFruit = getJapaneseFruit();
ただ、このために関数1個増やすのもどこに定義するとか関数名とか考えるのめんどくさいなぁ、、と思うこともありますよね。
そういう方は、無名関数がおすすめです。
const japaneseFruit = (() => {
switch (tgtFruit) {
case 'strawberry':
return 'いちご';
case 'melon':
return 'メロン';
case 'apple':
return 'りんご';
default:
return '';
}
})();
こんな感じで、関数名を入れずに定義できるので、関数名を考えなくてよいし、すっきりと書けます。
おわりに
どうでしたか?
もう少し書きたかったですが、letを回避するための書き方は他にも色々あるので(reduce、lodashなど)調べてみると良いと思います。
コードの書き方などは、人それぞれで宗教のように考え方が違う部分もあるので、一概にこう書かないといけない!に縛られなくても良いのかなと個人的には思います。
ただ、「きれいに書こう!」「読み手に伝わるように書こう!」という意識は、プログラムを書く上で忘れないようにしたいですね。

