ES6 におけるJavaScriptのクラス定義

このエントリーをはてなブックマークに追加

JavaScript はプロトタイプベースの言語であり、Java, C++, Python などのクラスベースの言語とは異なりクラスというものが存在しませんでした。しかしクラスベースのオブジェクト指向の書き方は人間に理解しやすくプログラムが書きやすく、何より他の人気のある言語の経験者にとって分かりやすいので、プロトタイプを使ってクラスと同等なことを実現するということがJavaScriptでも行われていました。 そして、ついに2015年6月に標準仕様が発行されたECMAScript 6(ES6)でJavaScriptにも「クラス」の文法が追加されました。 プロトタイプベースのJavaScriptでクラスに相当することは割りと簡単に実現できるので、そういう意味ではプロトタイプベースはより柔軟でクラスベースよりも表現力に優れていたのかもしれませんが、結局はほとんどの場合においてはクラスベースの考え方の方が人間に理解しやすく利用しやすかった…といったところでしょうか。

実行環境

2015年10月現在サポートが進んでいる最中で最新のブラウザでも完全にはサポートされていません。

クラスとコンストラクタの定義

ES6ではclassキーワードを使ってクラスを定義します。classのブロックの中でconstructorという名前の関数を定義するとそれがコンストラクタとして利用されます。

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

クラスのインスタンスの生成とコンストラクタの呼び出しには new 演算子を使います。

var alice = new Person('Alice', 7);

ちなみにnewはES6以前からJavaScriptに存在する機能です。newのJavaScript本来の仕様と使い方についてはES6以前のJavaScriptにおけるクラスの実現方法を参考にしてください

メンバ変数 (インスタンス変数)

上の例で出てきているように、クラスの内部でメンバ変数を定義・参照するにはthis.<プロパティ名>を使います。JavaScriptではJavaやC++ と違いthisを省略することは不可能なので注意してください。Python を知っている人はthisselfに相当するものだと思うと分かりやすいかと思います。インスタンス変数やメソッド呼び出しの際にPythonではselfを付けなければならないようにJavaScriptではthisが必ず必要です。

メソッド定義と呼び出し

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

  sayHello() {
    console.log("Hello, I'm " + this.getName());
  }

  getName() {
    return this.name;
  }
}

ES6ではclassブロックの中にconstructor以外の名前の関数を定義するとメソッドになります。 またメソッド内から他のメソッドの呼び出しを行う場合はthis.<メソッド名>(引数)を使います。 メンバ変数の場合と同様に、メソッド呼び出しの際にthis を省略することは不可能なので気をつけて下さい.

private, protected

JavaScript でクラスを実現する場合、メンバ変数やメソッドを privateprotected にすることはできません。 ただし名前規約で private なものを名前でわかりやすくして間違えてアクセスしないようにすることはできます。 Google の JavaScript のスタイルガイド では private なメソッド, メンバ変数は名前の末尾に _ をつけることが求められています。

継承

クラスの継承はES6では以下のように行います。

class Child extends Parent {
  constructor(a, b) {
    // 親クラスのコンストラクタ呼び出し
    super(a);
    // ...
  }

  // オーバーライド
  doSomething() {
    // 親クラスのメソッド呼び出し
    super.doSomething();
    // ...
  }
}

サンプル

このエントリーをはてなブックマークに追加
Home