altJS、すなわちJavaScriptの代わりとなる言語の筆頭である「TypeScript」。TypeScriptという言語名が示す通り、JavaScriptに「Type」、つまり型の概念を持ち込んだものです。本連載では、このTypeScriptの型に関して、さまざまな方向から紹介していきます。前回は関数の型に関して、型ガードやオーバーロードなどを紹介しました。今回から3回にわたって、オブジェクトのひな型となるクラスに関して、あれこれ紹介していきます。今回は、そのうちクラス構文そのものについてのあれこれを紹介していきます。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
クラスはECMAScript 2015(ES2015)でJavaScriptにも導入され、現在ではJavaScriptでも標準で利用できます。ただし、TypeScriptならではのクラス構文もあります。その辺りも含めて、基本形を紹介していきます。
クラスというのは、オブジェクトのひな型です。例えば、Scoreというクラスがあったとします。このクラスをリスト1の(1)のようにnewすることで、Scoreに含まれたメンバー(構成要素)がそっくりそのまま含まれたオブジェクトが生成されます。
const taro = new Score(); // (1) taro.name = "田中太郎"; // (2) taro.point = 98; // (3) taro.show("すばらしい!"); // (4)
第1回で紹介したように、この変数taroはオブジェクト型のScore型です。そしてScoreに定義されたメンバー、すなわちプロパティとメソッドが含まれていることになり、利用できるようになります。例えばScoreには、名前を表すnameプロパティと、点数を表すpointプロパティがあり、それらを表示するshow()メソッドがあるとすると、(2)と(3)でそれぞれのプロパティにデータを格納して、(4)で表示メソッドを実行しています。
このScoreクラスにメンバーを自分で定義する場合、TypeScriptではリスト2のようなコードを記述します。
class Score { name = ""; // (1) point = 0; // (2) show(msg: string):void { // (3) console.log(`${this.name}さんは${this.point}点です。`); } }
(3)がメソッドです。こちらの書式は、原則JavaScriptと変わりません。違うのは、引数と戻り値の型を記述する点です。これは、いわばfunctionキーワードを記述しないTypeScriptの関数ともいえます。もちろん、引数の省略やデフォルト値も利用できます。
一方、大きく違うのがプロパティの定義です。JavaScriptでは、コンストラクタを定義し、リスト3のようなコードを記述することでプロパティを設定していました*。
* ES2022では、JavaScriptでもフィールドでのプロパティ定義が可能となりました。
class Score { constructor() { this.name = ""; this.point = 0; } : }
もちろん、TypeScriptもこの方法でプロパティを定義できますが、もっと可読性の高い方法として、リスト2の(1)や(2)のようにクラスブロック直下に変数として定義できます。これをフィールドといいます。クラスをnewしてオブジェクトを生成する際に、このフィールドを基にプロパティが生成されます。
JavaScriptは歴史的にクラス構文がありませんでした。全てがオブジェクトであり、そのオブジェクトの中の構成要素をプロパティと呼んでいました。このプロパティにはデータ(変数)だけではなく、処理(関数)も格納できます。このうち、処理を格納したものをメソッド、データを格納したものを狭義のプロパティと呼んでいました。その後、ES2015でクラス構文が導入されても、その実はオブジェクトのままです。クラス内のデータ部分をきっちり定義する構文がありませんでした。上記のようにコンストラクタ経由で代入することで、データが追加され狭義のプロパティが生成されます。
一方、Javaなど最初からクラス構文がある言語では、クラス内でデータ部分をきっちり定義します。これをフィールドと呼んでいます。TypeScriptとES2022ではこの考え方を取り入れ、クラス内に定義したデータ部分をフィールドと呼んでいます。
Copyright © ITmedia, Inc. All Rights Reserved.