blog

JavaScriptのスタイルに関する5つの間違いをやめて、読みやすく保守性の高いコードを作ろう Quick Tips

コードを読みやすく保守しやすくするための簡単なヒント。 古いプロジェクトを開いたとき、何か新しいことを追加するとすぐにクラッシュしてしまうような、わかりにくいコードを見つけたことが何度あったでしょうか...

Jul 17, 2020 · 4 min. read
シェア

コードを読みやすく、保守しやすくするための簡単なヒント。

古いプロジェクトを開いたとき、何か新しいものを追加するとすぐにクラッシュするような、混乱したコードを見つけたことが何度ありますか?誰にでもあることです。

読みにくいjavascriptを減らすために、以下の例を用意しました。これらは私が過去に犯した間違いです。

複数の戻り値を持つ関数に対する配列分解の使用

複数の値を返す関数があるとします。可能な実装の1つは、以下のように配列のデストラクチャリングを使用することです:

const func = () => { const a = 1; const b = 2; const c = 3; const d = 4; return [a,b,c,d]; } const [a,b,c,d] = func(); console.log(a,b,c,d); // 1,2,3,4

上記はうまく機能しますが、若干の複雑さが生じます。

関数を呼び出してa,b,c,dに値を代入する場合、データが返される順番に注意する必要があります。ここでのちょっとしたミスが、デバッグの悪夢になりかねません。

さらに、関数からどの値を取得したいかを正確に指定することは不可能です。

その代わりに、オブジェクトの分解を使うことができます。

const func = () => { const a = 1; const b = 2; const c = 3; const d = 4; return {a,b,c,d}; } const {c,d} = func();

これで、関数から必要なデータを簡単に選択できるようになりました。また、コードを壊すことなく戻り変数を追加できるようになり、将来的にも安心です。

関数の引数にオブジェクト分解を使わない

オブジェクトをパラメータとして受け取り、そのオブジェクトのプロパティに対して何らかの処理を行う関数があるとします。素朴なアプローチは次のようなものです:

// function getDaysRemaining(subscription) { const startDate = subscription.startDate; const endDate = subscription.endDate; return endDate - startDate; }

上記のメソッドは期待通りに動作しますが、不要な2つの一時参照 startDate と endDate が作成されます。

より良い実装は、1行でstartDateとendDateを取得するためにサブスクリプションオブジェクトでオブジェクトの分解を使用することです。

// function getDaysRemaining(subscription) { const { startDate, endDate } = subscription; return startDate - endDate; }

さらに一歩進んで、パラメータに対して直接オブジェクトのデストラクチャリングを行うことも可能です。

// function getDaysRemaining({ startDate, endDate }) { return startDate - endDate; }

よりエレガントでしょう?

拡張演算子を使わない配列のコピー

forループを使って配列を走査し、その要素を新しい配列にコピーするのは、長くてかなり醜い。

同じ効果が、明確かつ簡潔な方法で拡張演算子を使用することによって達成することができます。

const stuff = [1,2,3]; // const stuffCopyBad = [] for(let i = 0; i < stuff.length; i++){ stuffCopyBad[i] = stuff[i]; } // const stuffCopyGood = [...stuff];

varの使用

constを使うことで、変数の再代入を確実に防ぐことができます。これにより、コードのエラーが減り、理解しやすくなります。

// var x = "badX"; var y = "baxY"; // const x = "goodX"; const y = "goodX";

変数を再代入する必要がある場合は、varの代わりにletを選んでください。

これはletがブロック・スコープでvarが関数スコープだからです。

ブロック・スコープとは、変数が定義されているコード・ブロックの内部でのみアクセスできることを示すもので、ブロック外の変数にアクセスしようとすると ReferenceError が発生します。

for(let i = 0; i < 10; i++){ //something } print(i) // ReferenceError: i is not defined

関数スコープとは、変数を定義した関数の中でのみ変数にアクセスできるというものです。

for(var i = 0; i < 10; i++){ //something } console.log(i) // 10

let も const もブロックスコープです。

テンプレート・リテラル値を使用しない

手動で文字列を連結するのはかなり面倒で、入力が混乱することがあります。以下はその例です:

// function printStartAndEndDate({ startDate, endDate }) { console.log('StartDate:' + startDate + ',EndDate:' + endDate) }

テンプレート・テキストは、文字列の補間をサポートする、読みやすく簡潔な構文を提供します。

// function printStartAndEndDate({ startDate, endDate }) { console.log(`StartDate: ${startDate}, EndDate: ${endDate}`) }

テンプレート・テキストには、改行を埋め込む簡単な方法も用意されており、いつものようにキーボードのEnterを押すだけです。

// 2行印刷 function printStartAndEndDate({ startDate, endDate }) { console.log(`StartDate: ${startDate} EndDate: ${endDate}`) }
Read next