モダンなJSの話──クラス

※この記事はInnovator Japan Engineers’ Blogで掲載されている記事を転載したものです。

ECMAScript6からのクラス定義

ECMAScript6以前ではnew演算子やprototypeプロパティを使ってクラスに近い機能を実現していましたが、ECMAScript6からはclassキーワードでクラスを定義できるようになりました。 classキーワードはこれまでのnew演算子やprototypeプロパティによるクラス定義のシンタックスシュガーです。

classキーワードを使ったクラス定義の方法には、クラス宣言とクラス式の2種類があります。

クラス宣言によるクラス定義の例:

クラス式によるクラス定義の例:

クラス式の場合、クラス名はあってもなくてもOKです。

MDN - Strict モード

ホイスティング(巻き上げ)

関数宣言ではホイスティングが行われますが(関数式ではされません)、class宣言やクラス式ではホイスティングされません。 したがって、クラス宣言やクラス式を使う場合はクラスを呼び出す前に、呼び出すクラスを先に宣言する必要があります。

※ホイスティングの概念について→モダンなJSの話──var/let/const

クラスは全てstrictモード

クラス宣言やクラス式で定義されたクラスは全てstrictモードになります。 strictモードの詳細についてはMDN - Strictモードをご参照ください。

constructorの定義は一度だけ

初期化を行うメソッドであるconstructorの定義は一度だけしか定義できません。 2回以上定義された場合はSyntax Errorが返されます。

#クラスのメソッド定義

getとset

ゲッターとセッターはそれぞれgetキーワードとsetキーワードで定義することができます。。 ゲッターはプロパティアクセスされたときに実行されるメソッドで、セッターはプロパティに値が代入された時に実行されるメソッドです。

getとsetの例:

静的メソッド

staticキーワードを用いることで静的メソッドをクラス内に定義することができます。 staticメソッドは、クラス名.静的メソッド名 で呼び出すことができます。

静的メソッドの例:

メソッドを静的メソッドにすることはできますが、プロパティをメソッドにすることはできません。 (TypeScriptではプロパティをstaticにすることができるらしいです。)

継承

継承はextendsキーワードで定義することができます。 親クラスのメソッドを呼び出したい場合は、superキーワードを使うことで呼び出し可能です。

継承の例:

ちなみに、super()がないとUncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructorとエラーがでます。

まとめ

classキーワードの登場によってJavaScriptでのOOPのあり方が変わったのではないでしょうか。 とはいえアクセス修飾子が実装されていなかったり、他のクラスベースの言語のOOPほど機能が充実していないため、まだ発展途上といった印象があります。

余談

JavaScriptのオブジェクトモデルについて知識(cf. オブジェクトモデルの詳細)があるとより深い理解が得られます。

参考