ES6(ES2015) から、JavaScript でも C++, PHP, Python などの言語と似た class 定義が可能となりました。下記では、Animal という名前のクラスを定義しています。
class Animal {
}
インスタンスを作成するには new を用います。
var o1 = new Animal();
インスタンスを削除するには delete を用います。
delete o1;
constructor() は、オブジェクトを生成する際に初期化関数として呼ばれるメソッドを定義します。下記の例では、オブジェクト生成時に種別(type)引数を渡し、オブジェクト内部のメンバ変数(this.type)に記録しています。
class Animal {
constructor(type) {
this.type = type;
}
}
var o1 = new Animal("Cat");
console.log(o1.type); // => Cat
クラス定義の中では、メソッドを定義することができます。メンバ関数は、オブジェクト.メンバ関数名() の形式で呼び出します。メソッドを定義する際は、function は不要です。
class Animal {
setType(type) {
this.type = type;
}
getType() {
return this.type;
}
}
var o1 = new Animal();
o1.setType("Cat");
console.log(o1.getType()); // => Cat
static は、スタティックメソッドを定義します。スタティック関数は、オブジェクトを生成しなくても、クラス名.スタティック関数名() で呼び出すことができるメソッドです。
class Animal {
static hello() {
console.log("Hello!");
}
}
Animal.hello(); // => Hello!
get はゲッター(getter)、set はセッター(setter)を定義します。ゲッター・セッターは、クラス利用者に対してはプロパティ(属性)のように簡単に代入や参照ができ、かつ、クラス開発者にとっては、代入・参照の際にメソッドがコールされ、代入・参照時にログを記録したり複雑な内部処理を実行することが可能となります。
class Animal {
get type() {
console.log("get:" + this._type);
return this._type;
}
set type(arg) {
console.log("set:" + arg);
this._type = arg;
}
}
var o1 = new Animal();
o1.type = "Cat"; // setter メソッドが呼ばれる
console.log(o1.type); // getter メソッドが呼ばれる
prototype を用いて、定義済のクラスに変数やメソッドを追加することができます。
class Animal {
}
Animal.prototype.type = "Unknown";
Animal.prototype.hello = function() {
console.log("Hello!");
}
var o1 = new Animal();
console.log(o1.type);
o1.hello();
クラスは継承することができます。継承元をスーパークラス(親クラス)、継承先をサブクラス(子クラス)と呼びます。Animal クラスを親クラスとして、Cat という子クラスを定義するには extends を用いて次のようにします。子クラスでは、親クラスのメソッドや変数を継承することができます。
class Animal {
hello1() {
console.log("Hello!");
}
}
class Cat extends Animal {
hello2() {
console.log("Hello Hello!");
}
}
var o1 = new Cat();
o1.hello1(); // => Hello!
o1.hello2(); // => Hello Hello!
super() は親のコンストラクタを呼び出します。super() は最初に使用する this よりも先に呼び出す必要があります。
class Animal {
constructor(type) {
this.type = type;
}
}
class Cat extends Animal {
constructor(name) {
super("Cat");
this.name = name;
}
}
var o1 = new Cat("Mii-chan");
console.log(o1.type); // => Cat
console.log(o1.name); // => Mii-chan
子クラスのコンストラクタを省略すると、子クラス作成時の引数を使用して親クラスのコンストラクタが自動的に呼び出されます。これは、constructor(...args) { super(...args); } と同じ動作となります。
class Animal {
constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
// constructor(...args) { super(...args); }
}
var o1 = new Cat("Mii-chan");
console.log(o1.name); // => Mii-chan
下記の様にして、親クラスのメソッドを呼び出すこともできます。
class Animal {
hello() {
console.log("Hello!");
}
}
class Cat extends Animal {
hello() {
super.hello();
}
}
var o1 = new Cat();
o1.hello(); // => Hello!
下記の様にクラス式を用いて、クラス名を持たない匿名クラスを作成することができます。
var o1 = class {
constructor() {
this.type = "Cat";
}
};
console.log(o1.type); // => Cat