クラスの型にまつわるあれこれ(3)〜クラスにおける特殊なthisと抽象クラスとstatic〜:TypeScriptのTypeあれこれシリーズ(7)
altJS、すなわちJavaScriptの代わりとなる言語の筆頭である「TypeScript」。TypeScriptという言語名が示す通り、JavaScriptに「Type」、つまり型の概念を持ち込んだものです。本連載では、このTypeScriptの型に関して、さまざまな方向から紹介していきます。前回は、クラスの型に関するあれこれを紹介する第2回として、クラスの継承や、クラスをnewしたオブジェクトそのものの型について紹介しました。今回は、クラスの型に関するあれこれを紹介する最後として、クラス内での特殊なthisの使い方、抽象クラス、staticを紹介します。
クラス内での特殊なthisの使い方
前回、前々回で紹介したクラス構文内でのthisの使い方は、同じクラス内や親クラス内のフィールドやメソッドを利用する場合の「this.」という記述でした。今回は、このthisのクラス内での特殊な使い方から話を始めていきます。
thisの特殊な使い方まとめ
クラス内でのthisの特殊な使い方は、以下の3種です。
- メソッドの引数としてのthis
- 戻り値としてのthis
- メソッドの引数の型としてのthis
それぞれ順に見ていきます。
JavaScriptのthisの弊害
最初に紹介するのが、メソッドの引数としてのthisです。ただし、この使い方を紹介する前に、なぜこのような使い方が必要なのか、その原因となるJavaScriptのthisの弊害について簡単に紹介します。JavaScriptのthisは使われる文脈に応じて、その内容がさまざまに変化してしまいます。TypeScriptでも、この性質は引き継がれざるを得ません。
例えば、リスト1のNameHolderクラスがあるとします。
class NameHolder { private name: string = "名無し"; // (1) constructor(name: string) { this.name = name; } showMyName(): void { console.log(`お名前: ${this.name}`); // (2) } showYourName(yourName: string): void { console.log(`私の名前は${this.name}で、あなたのお名前は${yourName}`); // (3) } } const nameHolder = new NameHolder("田中太郎"); // (4) nameHolder.showMyName(); // (5) nameHolder.showYourName("鈴木二郎"); // (6)
このコードの実行結果は、リスト2の通りです。
お名前: 田中太郎 私の名前は田中太郎で、あなたのお名前は鈴木二郎
リスト1の(4)でNameHolderをnewする際に、「田中太郎」を引数で渡しており、これが、(1)のフィールドnameに格納されます。(2)も(3)もこのフィールドnameを表示させています。その際のコードであるthis.nameのthisはNameHolderオブジェクト自身を指し、従って「.name」のnameは(1)のフィールドを指しています。実行結果も、この通りの処理となり問題なく「田中太郎」と表示されています(図1)。
ところが、このNameHolderをnewしたnameHolderを利用して、リスト3のコードを記述したとします。
const func1 = nameHolder.showMyName; // (1) func1(); // (2) const func2 = nameHolder.showYourName; // (3) func2("鈴木二郎"); // (4)
このコードの実行結果は、リスト4の通りです。
お名前: undefined 私の名前はundefinedで、あなたのお名前は鈴木二郎
なぜ、undefinedとなるのでしょうか。この種明かしは図2の通りです。
Copyright © ITmedia, Inc. All Rights Reserved.