脱初心者!JavaScriptプログラムの設計パターンを徹底解説


JavaScriptのよくあるプログラミングパターンが知りたい
初心者が間違いやすい基本的なパターンってなんだろう
なるべく最新のJavaScriptを使うにはどうすればいいの?

基本的なJavaScriptが書けるようになってきたら、より効率の良い安全なプログラムを書きたいと考えている人も少なくないでしょう。

しかしながら、初心者の方がいきなり高度な設計を学習しようとしてもなかなか前に進まないのも事実です。まず最初の取っ掛かりとしては、よく使われている基本的なパターンを学習するのが近道でしょう。

そこで、この記事では初心者でも今日からJavaScriptの基本的なプログラムパターンを理解するための方法について分かりやすく解説していきますので、ぜひ最後まで読んで理解を深めて頂ければ幸いです。

一人でも多くの方がJavaScriptの不安を解消できれば幸いです。

目次

基本構文のパターン

この章では、JavaScriptの基本構文においてよく使われているパターンをおさらいしてみましょう。主に、変数・配列のパターンと関数の書き方について学んでいきます。

変数・配列について

JavaScriptの変数定義は長らくvarが使われていましたが、現在はconst / letのどちらかしか使いません。もっと言えば、基本的にはconstを最優先で利用するようにし、どうしても変数を途中で変更したい時だけletを使うようにします。

簡単にまとめると次のようになります。

  • 【let】再宣言が不可
  • 【const】再宣言・再代入が不可

具体的なコードでも確認しておきましょう!

let item = 'リンゴ';

item = 'メロン';  //再代入はOK

let item = 'バナナ';  //再宣言はエラー
const item = 'リンゴ';

item = 'メロン';  //再代入はエラー

const item = 'バナナ';  //再宣言はエラー

constは一度定義したら再宣言・再代入ができなくなるので、イメージ的には定数を作るような感覚になるでしょう。誤って変数の値を変更してしまうことを防ぐ意味でも、constを最優先で利用するようにしましょう。

また、const / letはブロックスコープの特徴を持っており、変数をあるブロック内だけで完結できます。

次のサンプル例を見てください。

if(1) {
  var test1 = 100;
  let test2 = 200;
  const test3 = 300;
}
  
console.log(test1);
console.log(test2);
console.log(test3);

実行結果

100
エラー
エラー

この例では、IF文のブロック内に各種変数を定義しています。実行結果に注目して見ると、varで定義した変数以外はエラーになっていますよね?

つまり、const / letで定義した変数はIF文内だけで利用できるように作られているわけです。これにより、変数が意図しない場所で操作されてしまうのを防ぐことが可能になるわけです。

関数の書き方について

関数定義に使っていたfunctionキーワードですが、今ではアロー関数に置き換えることができます。
(コンストラクタの定義などにはfunctionを使います)

基本的な使い方例として次のサンプルを見てください!

//functionを利用したケース
function sample() {
  consoel.log('Hello');
}

//アロー関数を利用したケース
const sample = () => console.log('Hello');

アロー関数は【function】を【=>】に置き換えることができるわけですが、上の例みたいに実行する処理が1行だけの場合は{ }も記述不要になるのでコードがスッキリします。

関数に引数を指定する場合は次のようになります。

const sample = (name) => console.log(name);
  
sample('太郎');

非常に簡潔に書けて便利なのですが、すべてのfunctionを置き換えられるわけではありません。もっとも重要なポイントとしてはコンストラクタ定義でしょう。

例えば、次のようにコンストラクタ定義をアロー関数で行うとエラーになります。

const User = (name, age) => {
  this.name = name;
  this.age = age;
}

functionとアロー関数は【this】の扱い方が異なるのが大きな理由です。基本的に、コンストラクタ以外の関数定義であればアロー関数を優先的に使っていけば良いでしょう。

オブジェクトのパターン

この章では、オブジェクトを作る際によくありがちな基本パターンについて見ていきましょう。主に、コンストラクタ定義と名前空間について学んでいきます。

コンストラクタの作り方

JavaScriptでは独自のコンストラクタを定義する際に、functionを利用して次のように記述します。

const User = function(name, age) {
  this.name = name;
  this.age = age;
  
  this.showName = () => {
    console.log(this.name);
  }
}

主に、プロパティとメソッドを記述するわけですが、この例ではshowName()というメソッドを同時に定義していますね。

しかしながら、コンストラクタはプロパティだけを定義して、メソッドはプロトタイプを利用して定義するというのが基本パターンになります。理由としてはいくつかありますが、無駄なメモリを消費しないというのが大きなポイントでしょう。

例えば、先ほどのコンストラクタを利用して次のようにインスタンスを作成するとします。

const taro = new User('花子', 34);

taro.showName();

インスタンス【taro】を利用してshowName()を実行することができますね。

ところが、もしインスタンスを10個や100個という風にたくさん作るとどうなるでしょうか?その都度、すべてのインスタンスにメソッドの定義がコピーされますよね。

そうではなく、コンストラクタはプロパティの定義だけにして、メソッドの定義はプロトタイプにすれば良いのです。すると、インスタンスをいくつ作成してもコピーされるのはプロパティだけになります。

具体的なコード例を見てみましょう!

const User = function(name, age) {
  this.name = name;
  this.age = age;
}

//メソッドをプロトタイプに定義する
User.prototype.showName = function() {
  console.log(this.name);
}

この例では、コンストラクタにプロパティの定義だけを記述しています。その代わりに、UserプロトタイプにshowName()メソッドを定義していますね。

プロトタイプはUserインスタンスすべてにおいて共有できるので、インスタンスを作ってもいちいちメソッドがコピーされることはありません。

クラスの作り方

実は、最近のJavaScriptはクラス構文に対応しているので、前章で解説したプロトタイプなどをあまり意識せずにコンストラクタを作ることも可能です。

基本的な作り方は次のとおりです。

class クラス名 {
    constructor() {
        //プロパティの定義
    }


    メソッド() {
        //メソッドを定義する
    }
    ・
    ・
    ・

}

見て分かるように、プロパティとメソッドを1つの塊として記述するわけです。この時にプロトタイプなどを意識する必要はありません。

具体的なソースコード例を見てみましょう!

class User {
    constructor(name, age) {
         this.name = name;
         this.age = age;
    }

    showName(){
        console.log(this.name);
    }
}

const taro = new User('太郎', 30);

taro.showName();

実行結果

太郎

この例では、2つのプロパティと1つのメソッドを定義していますね。

クラスによるインスタンスの作成方法はこれまでと同様なので心配しないでください。

また、クラス構文を利用すると継承も次のように簡単に行えます。

class Man extends User {
  showAge() {
    console.log(this.age);
  }
}

extendsを使って継承したいコンストラクタ名を指定するだけです。この例では、showAge()メソッドしか定義されていないManクラスにUserクラスを継承しています。

実際にインスタンスを作成して実行してみましょう。

const jiro = new Man('次郎', 28);
  
jiro.showName();
jiro.showAge();

実行結果

次郎
28

ManクラスでshowName()メソッドは定義していませんでしたが、見事に実行されていることからUserクラスを正常に継承できていることが分かります。

Babelの基本パターン

この章では、Babelを使った基本的なトランスパイル手法について見ていきましょう。主に、Babelの概要と実際の使い方について学んでいきます。

最新の構文が使えるBabelについて

JavaScriptで効率の良いプログラムを書こうと考えると、どうしても最新のJavaScript仕様を使う必要がでてきます。

ただし、すべてのブラウザが最新のJavaScriptに対応していないうえ、どの構文が使えるのかバラバラです。そこで、登場するのがBabelです。

【Babel】

Babelを利用すると、最新の仕様で書かれたプログラムを古いJavaScriptに変換してくれるのです。

これにより、ブラウザの対応を待たなくても今すぐ効率の良いJavaScriptを利用してプログラミングができるというわけです。

Babelの概要図

Babelを利用するにはNode.jsの開発環境が必要になるので、まだ準備ができていないという方は次の記事を参考にながら準備するのが良いでしょう。

Babelのインストールはnpmを利用して簡単に導入できます。

npm install --save-dev @babel/core @babel/cli @babel/preset-env

基本的なトランスパイルについて

Babelを利用して古いJavaScriptへトランスパイル(変換)するには、まず最初に専用の設定ファイルを用意する必要があります。

ファイル名を【babel.config.json】として、次のように記述します。

const presets = [
   [
     '@babel/env'
   ]
];
 
module.exports = {presets};

トランスパイルするプリセットの設定を行うのですが、基本的には【@babel/env】を指定しておけば良いでしょう。

次に、package.jsonファイルの【scripts】プロパティに次のような記述を追加します。

{
    ・
    ・
    ・
  "scripts": {
    "babel": "./node_modules/.bin/babel src --out-dir lib"
  },
    ・
    ・
    ・
}

このように記述することで、Babelを使ったトランスパイルを【npm run babel】というコマンドで実行できるようになります。

それでは、新しい関数の書き方であるアロー関数を書いてみましょう。

const sample = () => {

    console.log('Hello Babel');

}

これをBabelでトランスパイルします。

$ npm run babel

すると、libディレクトリ内にトランスパイルされたファイルが生成されているので、中身を見てみいましょう。

var sample = function sample() {

    console.log('Hello Babel');

};

このように、アロー関数はfunctionキーワードに置き換わっていますね。ついでに、constがvarに変わっている点にも注目です。

つまり、古いJavaScriptの仕様に変換されているので、ほとんどのブラウザに対応することができるわけです。

まとめ

今回は、JavaScriptのプログラム設計の基本について学習をしました。

最後に、もう一度ポイントをおさらいしておきましょう!

  • 変数・配列・関数の基本パターンを覚えると効率がよくなる
  • 従来からのコンストラクタを使うか新しいクラス構文を使おう
  • Babelによるトランスパイルで最新の仕様を活用しよう

上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!

この記事を書いた人

フリーランスのIT系ライターを10年従事する兵庫県出身の40歳。侍ブログ編集部としては、これまで270記事以上を執筆。
30歳を過ぎてから独学でJavaScript, Node.js, Linuxを習得した経験を活かし、初心者が迷わない記事作成を意識しながらプログラミングの楽しさを知ってもらうために活動しています。趣味はキャンプと登山です。

目次