TokyoFacebookTwitterHatenaPocketJavaScriptに限らず、プログラミングの基本を学んだら何か動くモノ(プライベートプロジェクト)を作ってみたくなります。実際にどうやって進めたらいいのでしょうか?読者からときどき聞こえてくるのは、自分自身でJavaScriptのプロジェクトを進める方法が分からないということです。理由の1つは、記事では具体的な手順が示されるので、手順そのものを自分で考えることがないからです。プロジェクトに手こずるもう1つの理由は、まだ作りかけの状態なのに他人の完成作品と比べて落胆することです。実際のプロジェクトの進め方は記事(私のも含めて)で説明しているほど単純ではありません。現実には、プロジェクトは完璧なコードをガンガン書くことではなく、たくさんの試行錯誤とリファレンスを幾度も参照して少しずつできあがるものなのです。本記事では、自分でJavaScriptプロジェクトを進めていく方法を説明します。重要な注意事項:記事にはいくつかのサンプルコードを掲載しています。なじみのないコードなら、ひとまず飛ばしてしまって構いません。記事の主旨はプロジェクトへの取り組み方の全体像を理解することであり、技術的な詳細ではありません。最初に基本を身に着けよう少なくともJavaScript(そしてプログラミング全般)の基本を身に着ける必要があります。変数、関数、if文、繰り返し文、配列、オブジェクト、DOM操作メソッド(getElementById、querySelectorAll、innerHTMLなど)が含まれます。必要ならばこの記事を読み終えてからGoogle検索するかMDNで探してください。一度こうした概念に慣れたら、もうif文をどう書くかに悩まず製作に没頭できるので、作業はぐっと速くなるでしょう。多くの人がこの手順をおろそかにするので、結果的に遠回りをしています。ゲームをするときに、まだレベル1もできていないのにレベル3でプレイするようなものです。すればイライラは避けられます。計画を立てるいきなりプロジェクトに飛びついて一直線の手順でこなすのではなく、全体像を眺める時間を作ります。どのようなことが必要なのでしょうか。カウントダウン時計を作るなら、時間の計測、データの保持、数字の表示場所、時計の操作などの手段を考える必要があります。この段階ではまだ技術的な泥沼にはまらずに、なにがしたいのかをしっかり考えてください。全体の計画という道しるべがあれば、迷走することはありません。ソフトウェア設計の世界ではよくこのことをユースケース分析と呼んでいます。コード無しで書いていく計画ができあがったら、詳細を考えます。個人的に最良だと思う方法は、プロジェクトの各パートにおいてなにが求められるのかを具体的に書き出すことです。このとき、まだコードを書かずに言葉だけで記述するのがカギです。これはpseudocode(疑似コード)と呼ばれます。pseudocodeなら構文を気にすることなく、プロジェクトの動作だけに思考を集中できます。カウントダウン時計の場合なら、書き出した内容は次のようになるでしょう。現在時刻を取得する終了時刻を決定する現在時刻と終了時刻の差から、残り時間を求めるカウントダウン中には残り時間の取得処理を繰り返すカウントダウン中には画面上に残り時間を表示する内容を書き出したら、次は以下のように、各パートごとに小さく分解していきます。カウントダウン中には画面に残り時間を表示する時刻を「時・分・秒」に分ける1つのコンテナに「時」を表示する「分」「秒」も同様にするいったんロジックを書き出してしまえば、コードを書くのが格段に楽になります。「カウントダウン時計を作れ」と言われて全コードを書くよりも、「終了時刻から現在時刻を引き算する」といった具体的な手順にしたがってコードを書くほうが簡単だからです。このとき最初から完璧に全手順を書き出す必要はありません。書き出した手順は流動的ですから、手順を加えたり、取り除いたり、間違えたりして、試行錯誤しながら改良すればよいのです。小さな部分に分けて製作する手順ができあがったら、小さな部分に分けてコードを書き始めます。カウントダウン時計の場合、現在時刻の取得から始めるでしょう。Date().getTime();console.log(currentTime);次に、カウントダウン終了時刻を取得します。30).getTime();console.log(endTime);自分の時計を作るときは上のサンプルのように特定の日付を終了日にできますが、本記事のサンプルがある日で停止しては困るので、終了日を10日後としています(JavaScriptで使う単位がミリ秒なので、10日間はミリ秒に変換されます)。10*24*60*60*1000;console.log(endTime);コードを小さな部分に分けて書いていくほうが良い理由は、次のようなことです。次の手順に進む前に、作った機能が正常動作するかを確認できるほかのたくさんの関連要素に悩まされず、考えやすい一度に大量のことを気にかける必要がないため、作業が速いエラーの発見や防止がしやすい必要なときにテストできる往々にして、部品として使い回せるコードが書ける各パーツを結合する各部分の準備ができたら、結合します。この段階の一番大切なことは、単独では動作する各パートが、結合後も動作するか確認することです。変更が必要な場合もあります。以下は、カウントダウン時計で残り時間の計算のために開始時刻と終了時刻を結合するときの例です。timeconsole.log(getRemainingTime(endTime));小さな部品に分けてから結合する方法だと、頭の中で同時にたくさんのことに注意を払う必要がないため、一度に全体を作ろうとするよりもずっと簡単です。残り時間を取得する関数ができたので、繰り返し実行して表示時間を更新し続けるようにします。このときのHTMLは以下です。id="clock"></div>JavaScriptは次のようになります。requestAnimationFrame(showTime);}requestAnimationFrame(showTime);上の例では画面に残り時間を表示するためにshowTime関数を加えました。関数の最後に加えたrequestAnimationFrame(showTime)は、ブラウザー側が準備でき次第showTimeを再実行します。これでパフォーマンス面で有利な方法を使って表示時刻を更新し続けられます。知っての通りカウントダウンはすべてミリ秒単位です。次の手順はミリ秒を日・時・分・秒に変換します。ここまでに説明してきた方法(小さな手順に分解するなど)を使って、最初にミリ秒を秒に変換し、どうなるかを確認してから関数に組み入れます。同じ手順で分・時・日を計算できます。最終的な結果は次のようになります。requestAnimationFrame(showTime);}requestAnimationFrame(showTime);実験とテストこの段階ですでに、たくさんの実験とテストを繰り返して動作確認をしてきました。動作するならば、いろいろ試して不具合がないか確認してください。if文を加えて、時計が0で止まるようにします。}}値に1000ミリ秒(1秒)を使う理由は、もし0を使うと時計が行き過ぎて-1まで進んでしまう可能性があるからです。時計が秒よりも小さい単位で動いている場合、終了条件式を1秒よりも小さい値にしてください。この問題は記事の執筆中に友人が指摘してくれたことで、これもまた最初のコードが完璧ではないことを示す良い例です。ここまでの説明は、まさに次に述べるポイントにつながります。外部の助けを求める外部に助けを求めることは、プロジェクトのどの時点においても大切なことです。「助け」は参考文献でも、ほかの人でもかまいません。この話を持ち出したのは、開発者はなにも見ず誰の手も借りずに座って完璧なコードを書ける...という、よくある誤解が蔓延しているからです。ベテラン開発者が頻繁に調べものをするのを見て、新人の開発者が驚いたという話をよく耳にします。実際のところすべてを知り尽くすのは不可能なので、情報を探し当てる力というのは一番大切な技術なのです。ツールや技術が変化しても、「学ぶ技術」は風化しません。コードのリファクタリング(再構築)プロジェクトを完成する前に、コードのリファクタリング(見直し・再構築)を検討してください。以下は、改良のために自分自身に問いかけたい質問です。コードは簡潔で読みやすいか?もし簡潔さと読みやすさのどちらか片方を選ばなければならないとしたら、よほどパフォーマンスの問題がない限り、通常は読みやすさを優先します。読みやすければ、メンテナンス、更新、修正も楽になるからです。コードは効率的か?たとえば、もしコード内で同じ要素を何度も繰り返し参照するなら、その要素は変数に格納してコードの負担を減らしたほうが良いでしょう。カウントダウン時計のサンプルでも以下の部分を次のように処理しました。document.getElementById('clock');関数や変数の名前は分かりやすいものになっているか?たとえば、showTimeのような関数名は、stとするよりもずっと分かりやすいです。これはとても大切な点です。ときに開発者はそのときピッタリだと思って略称を付けたために、あとからなにを略したのか思い出せず途方に暮れることがあります。名前が分かりやすいかどうかを知るには、コードを書かない人に名前の由来を簡単に説明できるか考えてみると良いでしょう。名前の衝突の可能性はないか?たとえば、「container」のような名前だと、どこかほかの部分で同じ名前が使われている確率が高そうです。expression、IIFE)に入れることです。これなら時計のコードはすべての変数にアクセスできますが、ほかのコードからはアクセスできなくなります。オブジェクトになにかを追加したときにカンマを加えるのを忘れてはいませんか?表示は適切になっているか?カウントダウン時計のサンプルで、1桁の表示に0が付いたら見やすくなります(10:9ではなく10:09と表示)。1つの方法は値が9以下なら先頭に0を加えることですが、少し面倒です。別のサンプルコードで見つけた賢いワザは、最初に先頭に0を追加して、次にslice(-2)で、値がなんであれ最後の2桁を取得するという方法です。コードは次のようになります。先の処理では、出力にゼロを追加するコードは単独の関数にまとめられます。これで重複が減り、コードも読みやすくなります。60);プロジェクトを新鮮な目で見るとどう見えるか?数日置いてから、自分のコードを見直してください。新鮮な目で見ると、もっとすっきり書ける箇所や効率化できる箇所が発見できるでしょう。手直しすると、コードはますますエレガントになっていきます。それを納品すれば、コードを見た人びとは「いったいどうやったらこんなに完璧に書けるのか」と驚くでしょう。数カ月後にあらためて見直すと、もっとうまくできたはずなのにと気がつくでしょう。私の友人の1人は、進歩している証だから良いことなんだと言ってくれました。興味があれば、時計のサンプルのデモを見てください(若干のスタイルを追加しています)。最後にプログラミングのプロジェクトが単純に順を追ってまっすぐ進展することはまずありません。この記事で覚えておいてほしいもっとも重要なことは「一度に全体を作ろうとするよりも、小分けにして試しながら作るほうがずっと良い」という点です。以前にJavaScriptのプロジェクトで苦しんだ経験があるならば、この記事が役に立つことを祈ります。Burnettが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。Berhanuコーディングのスキルが上がるのを助けるのが大好きなWeb開発者です。Codeで豆知識や裏技を公開しています。自分のWebサイトを単に自分のだからではなく、客観的な観点から見ることをおすすめしています。