料金シミュレーターで学ぶ、綺麗なJavaScript(jQuery)の書き方
HTML/CSSはそこそこ綺麗に書けるようになってきたけど、JavaScript(jQuery)が全然綺麗に書けない...という方に向けた記事です。
(jsの最低限の書き方の知識はあるという前提)
今回は、料金シミュレーターを題材にして、どのようにjsを綺麗に書いていくかを解説していきます。
サンプルコードはこちらです。
(初心者の方にも馴染みのあるjQueryでサンプルコードを書いています)
See the Pen
js勉強問題 料金シミュレーター by dadada (@dadada-dadada)
on CodePen.
jsを書く時に意識するポイント
コードの解説の前に、jsを書く時に意識するポイントをいくつか紹介します。
変数名は分かりやすく
// 金額の変数名の場合...
// 分かりやすい
const price = 1000;
// 略し過ぎて他の人が見たら分からない
const p = 1000;
// おしりの数字はなんだろう...2や3もあるのかな?って思われる
const price_1 = 1000;
このように、変数名は略し過ぎず、分かりやすく付けましょう。
もちろん、以下のように紛らわしい書き方も辞めましょう。
const price_1 = 1000;
const price_3 = 1000;
// 1と3があるけど、2はあるのかな...
コメントを書く
長い処理や複雑な処理などにはコメントを書きましょう。
どのような処理をしているか、引数の型や内容、戻り値の型や内容など、コメントをしっかりと書くことで、時間が経っても自分でどのような処理を書いていたのかをすぐ思い出せます。(自分が書いたコードでも1週間も経てば内容を忘れています)
JSDocというコメントの書き方もあります。
参考:https://qiita.com/tarotaro1129/items/c7b742f3602c7749a29d
ネスト(ifやforの入れ子)を浅くする
for (let i = 0; i < array.length; i++) {
if(a) {
if(b) {
for (let f = 0; f < array.length; f++) {
if() { ... }
}
} else{
// ...
}
}
}
このように、何層も入れ子にするとコードの可読性がとても悪くなります。できれば2階層くらいまでに抑えたいです。
処理ごとに関数で分けたり、工夫をすれば何階層にもならずに済むはずです。
処理と実行を分ける
例えば、ボタンをクリックしたらconsoleをする処理を書くとします。
$('button').on('click', function() {
console.log(1)
});
このように書くと思います。
この場合、「処理」がconsoleの部分で、「実行」が$('button').on('click', 〜 の部分になります。
先程のコードを「処理」と「実行」で分けてみます。
const hoge = function() {
console.log(1)
}
$('button').on('click', function(){
hoge();
});
このように、「処理」を関数化することで、他の部分でも使い回せるようになります。
今回のサンプルはconsole一行のみですが、実際は何十行も「処理」のコードがあります。
前のセクションで解説した「ネストを浅くする」という観点からも、このように「処理」の部分を分ければネストも浅くなって、コードの可読性が上がります。
このように、「処理」と「実行」を分けていれば、仕様変更にも柔軟に対応できます。
例えば、ボタンが1つ増えて、consoleの他にも「要素を取得して○○する」という処理が増えたとします。
「処理」と「実行」を分けていれば綺麗で見やすいコードになります。
// 処理と実行を分けていない場合
// (同じコードを2度書いている)
$('button#a').on('click', function(){
const $piyo = $('#piyo');
$piyo.aaa();
console.log(1);
});
$('button#b').on('click', function(){
const $piyo = $('#piyo');
$piyo.aaa();
console.log(1);
});
// 処理と実行を分けた場合
const hoge = function() {
const $piyo = $('#piyo');
$piyo.aaa();
console.log(1);
}
$('button#a').on('click', function(){
hoge();
});
$('button#b').on('click', function(){
hoge();
});
コードの解説(綺麗なコードを書くための考え方)
先程解説したポイントを踏まえてコードを書いています。
jsを抜粋すると、以下のようになります。
// 必要な要素を最初に全部取得しておく
const $inputPrice = $('#js-input-price');
・
・
・
// 合計金額計算の関数
const calc = function() {...}
// エラーメッセージ要素を生成する関数
const createErrorMessage = function() {...}
// エラーチェック関数
const errorCheck = function() {...}
// ここから上が「処理」のコード
// ---------------------------------------------------------------------------------------------------------
// ここから下が「実行」のコード
// ページ全体が読み込まれたら実行
$(window).on('load', function() {
// エラーチェックをして、OKなら合計金額を表示する関数を実行
});
// 本体価格入力時に実行
$inputPrice.on('input', function() {
// エラーチェックをして、OKなら合計金額を表示する関数を実行
});
// オプションチェック変更時に実行
$checkOption1.on('input', function() {
// エラーチェックをして、OKなら合計金額を表示する関数を実行
});
$checkOption2.on('input', function() {
// エラーチェックをして、OKなら合計金額を表示する関数を実行
});
最初に要素を取得
要素や値などの変数は、できるだけ上のほうでまとめて定義しておきます。
/**
* 必要な要素を最初に全部取得しておく
*/
const $inputPrice = $('#js-input-price');
const $checkOption1 = $('#js-check-option-1');
const $checkOption2 = $('#js-check-option-2');
const $inputTotalPrice = $('#js-input-total-price');
const $inputTotalPriceInTax = $('#js-input-total-price-in-tax');
一箇所に変数をまとめておけば、使いたい変数を探す時にその一箇所を見るだけで済みます。
逆に、色々な箇所で変数を定義していたら、色々な箇所を探さなければいけません。
また、一番上で定義しておけば、どの箇所でも変数を使えます。
「一番上で変数を定義する」をまずは意識しましょう。
(関数を作る時も、関数の一番最初で変数を定義するようにしましょう)
「処理」を関数化する
今回は3つの処理があるので、3つの関数を作っています。
- 合計金額計算の関数
- エラーメッセージ要素を生成する関数
- エラーチェック関数
このように関数化しておけば、色々な箇所(合計金額入力時やページ読み込み時など)で同じ処理を呼び出せます。
関数化した処理を「実行」するコードを作る
今回は、3つのタイミングで処理を実行しています。
- ページ読み込み時
- 本体価格入力時
- オプションチェック時
「処理」を関数化しておいたので、様々なタイミングで関数を呼び出せます。
こうしておけば、例えば、オプションのチェックがもう一つ増えても、
$増えたオプション要素.on('input', function() {
// エラーチェックをして、OKなら合計金額を表示する関数を実行
});
このようにinputイベントを作るだけで追加対応は終わりです。
まとめ
自分が読んでも分かりにくいコードは、他人が読んでも分かりにくいです。
まずは自分が読みやすいと思えるようなコードを書けるように練習しましょう。
自分が書いたコードを人に見てもらって感想を聞くのも良いと思います。
そして、まずは「処理」と「実行」を分ける癖を付けるようにしましょう!そうすれば自然と綺麗なコードになるはずです。