クラス(Class)

[up] [prev] [next]

目次

クラスを定義する(class)

ES6(ES2015) から、JavaScript でも C++, PHP, Python などの言語と似た class 定義が可能となりました。下記では、Animal という名前のクラスを定義しています。

JavaScript
class Animal {
}

インスタンスを作成するには new を用います。

JavaScript
var o1 = new Animal();

インスタンスを削除するには delete を用います。ただし、var や let で宣言した変数は削除できず、通常モードであれば false を返し、Strictモードであればエラーとなります。

JavaScript
o1 = new Animal();
var o2 = new Animal();
let o3 = new Animal();

delete o1;  // 通常モードだと消える。Strictモードだと o1 自体を作成できない。
delete o2;  // 通常モードだとエラーにはならないが消えない。Strintモードだとエラー
delete o3;  // 通常モードだとエラーにはならないが消えない。Strictモードだとエラー

コンストラクタ(constructor)

constructor() は、オブジェクトを生成する際に初期化関数として呼ばれるメソッドを定義します。下記の例では、オブジェクト生成時に種別(type)引数を渡し、オブジェクト内部のメンバ変数(this.type)に記録しています。

JavaScript
class Animal {
  constructor(type) {
    this.type = type;
  }
}

var o1 = new Animal("Cat");
console.log(o1.type);         // => Cat

フィールド(field)

クラスはクラスフィールドを持つことができます。クラスフィールドはコンストラクタの中で初期化します。

JavaScript
class Animal {
  constructor(type) {
    this.type = type;
  }
}

var o1 = new Animal("Cat");
console.log(o1.type);         // => Cat

ES2022 からはコンストラクタが無くても宣言・初期化することができるようになりました。

JavaScript
class Animal {
  type = "unknown";
}

メソッド(method)

クラス定義の中では、メソッドを定義することができます。メンバ関数は、オブジェクト.メンバ関数名() の形式で呼び出します。メソッドを定義する際は、function は不要です。

JavaScript
class Animal {
  setType(type) {
    this.type = type;
  }
  getType() {
    return this.type;
  }
}

var o1 = new Animal();
o1.setType("Cat");
console.log(o1.getType());     // => Cat

プライベート(#)

ES2022 からはフィールド名やメソッド名の先頭に # をつけることで、クラスの外部からアクセスできないプライベートフィールド、プライベートメソッドを定義できるようになりました。クラスの外部で不用意に変更されることがなくなるため、プログラムの安全性を高めることができます。

JavaScript
class Aminal {
  #type = "unknown";
  #func() { .... }
}

var o1 = new Animal();
console.log(o1.#type);       // エラー
o1.#func();                  // エラー

スタティック(static)

static は、スタティックフィールドやスタティックメソッドを定義します。スタティックフィールドやスタティックメソッドは、オブジェクトを生成しなくても、className.fieldNameclassName.methodName() で参照することができます。

JavaScript
class Animal {
  static msg = "Hello!";
  static hello() {
    console.log("Hello!");
  }
}

console.log(Animal.msg);   // => Hello!
Animal.hello();            // => Hello!

スタティックイニシャライズブロック

スタティックフィールドの初期化に式や文を使用したい場合、これまではクラス定義の外に記述する必要がありました。

JavaScript
class Foo {
  static x = 123.4;
  static y;
}
Foo.y = Foo.x * 2;

ES2022 ではこれをスタティックイニシャライズブロックとしてクラス定義内に記述できるようになりました。

JavaScript
class Foo {
  static x = 123.4;
  static {
    Foo.y = Foo.x * 2;
  }
}

ゲッター(getter)とセッター(setter)

get はゲッター(getter)、set はセッター(setter)を定義します。ゲッター・セッターは、クラス利用者に対してはプロパティ(属性)のように簡単に代入や参照ができ、かつ、クラス開発者にとっては、代入・参照の際にメソッドがコールされ、代入・参照時にログを記録したり複雑な内部処理を実行することが可能となります。

JavaScript
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)

prototype を用いて、定義済のクラスに変数やメソッドを追加することができます。

JavaScript
class Animal {
}
Animal.prototype.type = "Unknown";
Animal.prototype.hello = function() {
  console.log("Hello!");
}

var o1 = new Animal();
console.log(o1.type);
o1.hello();

継承(extends)

クラスは継承することができます。継承元をスーパークラス(親クラス)、継承先をサブクラス(子クラス)と呼びます。Animal クラスを親クラスとして、Cat という子クラスを定義するには extends を用いて次のようにします。子クラスでは、親クラスのメソッドや変数を継承することができます。

JavaScript
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() は親のコンストラクタを呼び出します。super() は最初に使用する this よりも先に呼び出す必要があります。

JavaScript
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); } と同じ動作となります。

JavaScript
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

下記の様にして、親クラスのメソッドを呼び出すこともできます。

JavaScript
class Animal {
  hello() {
    console.log("Hello!");
  }
}

class Cat extends Animal {
  hello() {
    super.hello();
  }
}

var o1 = new Cat();
o1.hello();          // => Hello!

クラス式

下記の様にクラス式を用いて、クラス名を持たない匿名クラスを作成することができます。

JavaScript
var o1 = class {
  constructor() {
    this.type = "Cat";
  }
};
console.log(o1.type);     // => Cat

[up] [prev] [next]
Copyright (C) 2017-2023 杜甫々
改訂版初版:2017年12月17日、最終更新:2023年9月10日
http://www.tohoho-web.com/js/class.htm