JavaScript(ECMAScript2015)のクラスを試してみる

/

導入

前回gulpとBabelを使って次世代のJavaScriptであるECMAScript2015を利用できる環境が出来たので、今回はECMAScript2015で追加されたクラスの機能を試してみました。

gulpとBabelで次世代JavaScript(ECMAScript2015)をコンパイルする/kotatt

Class

class Car {
  constructor(name) {
    this.name  = name;
    this.speed = "50km/h";
  }
  run() {
    console.log( this.name + "が走っています。" );
  }
  klaxon() {
    console.log("Beeeee!!!");
  }
}

var car = new Car("カローラ");
console.log(
  "この車は「" + car.name + "」です。「" +
  car.speed + "」の速度で走る事ができます。"
);

car.run();
car.klaxon();

この車は「カローラ」です。「50km/h」の速度で走る事ができます。
# run();
カローラが走っています。
# klaxon()
Beeeee!!!

クラスの定義

class Car {
  constructor(name) {
    this.name  = name;
    this.speed = "50km/h";
  }
}

ECMAScript2015ではclassキーワードを使いブロックの中でクラスを定義します。
ブロック内で定義されているconstructorはクラスのインスタンス作成時に呼び出される特殊なメソッドで、クラスのインスタンスの作成時に与えられた引数はコンストラクタに渡され、この値を元にクラスの初期化実行されます。
construcotrという名前のメソッドは各クラスで一つしか定義出来ません。

作成されたクラスはnewキーワードによって呼びだされます。

var car = new Car("カローラ");

メソッドの定義

オブジェクト志向プログラミングではメソッドを使ってクラス毎の振る舞いを実装します。

Carクラス内ではrun()メソッドとklaxonメソッド()を定義しています。
run()メソッドでは constrctorによって設定されたインスタンスのnameパラメーターを参照してるため、インスタンス毎に異なるメッセージを出力します。

var car = new Car("カローラ");
car.run();
var another_car = new Car("フィアット");
another_car.run();
カローラが走っています。
フィアットが走っています。

継承

ECMAScript2015では extends キーワードによってクラスの継承を行います。

class SportsCar extends Car {
  constructor(name) {
    super(name);
    this.speed = "100km/h";
  }
  run() {
    console.log( this.name + "が速いスピードで走っています。" );
  }
  klaxon() {
    super.klaxon();
  }
}

var sports_car = new SportsCar("ポルシェ");

console.log(
  "この車は「" + sports_car.name + "」です。「" +
  sports_car.speed + "」の速度で走る事ができます。"
);

sports_car.run();
sports_car.klaxon();

console.log(sports_car.constructor.name);


class Truck extends Car {
  constructor(name) {
    super(name);
    this.speed = "70km/h";
  }
  run() {
    console.log( this.name + "が荷物を運んでいます。" );
  }
  klaxon() {
    super.klaxon();
  }
}

var truck = new Truck("js運送トラック");
console.log(
  "この車は「" + truck.name + "」です。「" +
  truck.speed + "」の速度で走る事ができます。"
);

truck.run();
truck.klaxon();

console.log(truck.constructor.name);
この車は「ポルシェ」です。「100km/h」の速度で走る事ができます。
ポルシェが速いスピードで走っています。
Beeeee!!!

この車は「js運送トラック」です。「70km/h」の速度で走る事ができます。
js運送トラックが荷物を運んでいます。
Beeeee!!!

super

親クラスのメソッドやコンストラクタを参照するにはsuperキーワードを使います。
上の例では同じくCarクラスを継承したSportsCarクラスとTruckクラスの2つのクラスが、コンストラクタやその他のメソッドでsuperキーワードによって親クラスの定義を参照した際には同じ振る舞いをしていますが、それぞれのクラスで新たに定義しなおしたメソッドに関しては異なる振る舞いをしています。

静的メソッド

static キーワードを使うと静的メソッドを定義出来ます。静的メソッドはインスタンスを作成する事なくクラスから直接呼び出すことが出来ます。

class Drums {
  constructor(){}

  static hit() {
    console.log("ドン!ドン!ドン!");
  }
}

Drums.hit();
ドン!ドン!ドン!

あとがき

前回アロー関数に少し触れましたが、クラスの機能もECMAScript2015で実装された代表的なものの一つです。
従来のJavaScriptでクラスの機能を使う際にはprototypeを利用した独特の方法でクラスの機能を実装しなければならなかったので、他の言語と同様にシンプルな方法で書けるクラスの機能が待望されていました。

内容自体は普通のクラスの機能ですが、JavaScriptで普通のクラスが書けるという意味ではやはり重要な機能だと思います。すでに多くの人にとって使い慣れた機能なので各ブラウザがECMAScript2015に対応しネィティブで書けるようになった時に速いスピードで世の中のJavaScriptの書き方に影響を与える可能性もありますし、すでに他の言語で慣れている人にとっては扱うのも容易だと思うのでECMAScript2015の代表的な機能としてまずは押さえておきました。

参照

Classes/MDN JavaScriptリファレンス