はいさい!ちゅらデータぬオースティンやいびーん!
概要
TypeScriptでclass
構文を書く時に、constructor
関数の引数にpublic
、protected
およびprivate
の接頭辞を使うと、同時にインスタンス変数の定義ができるので、その手法を紹介します。
背景
AngularでServiceの説明を読んでいたのですが、不思議な書き方を見て気になりました。
export class HeroService {
private heroes: Hero[] = [];
constructor(
private backend: BackendService, // これです
private logger: Logger) { }
getHeroes() {
this.backend // しかもこうやって定義していないはずのクラス変数を使っているし
.getAll(Hero).then( (heroes: Hero[]) => {
this.logger.log(`Fetched ${heroes.length} heroes.`);
this.heroes.push(...heroes); // fill cache
});
return this.heroes;
}
}
どういうことだろうと思い、TypeScriptのドキュメントを調べました。
その結果を本記事で備忘録代わりにまとめます。
コンストラクター割り当て(Constructor Assignment)
このTypeScriptの構文をConstructor Assignment
と言っています。
TypeScriptならではの速記手法です。
例えば通常、こう書くでしょう。
class MyObject {
private name: string;
constructor(name: string) {
this.name = name;
}
public getName(): string {
return this.name;
}
}
const obj = new MyObject("austin");
console.log(obj.getName()); // "austin"
しかし、同じことが以下のような省略記述で表現できます。
class MyObject {
constructor(private name: string) {}
public getName(): string {
return this.name;
}
}
const obj = new MyObject("austin");
console.log(obj.getName());
かなりすっきりしますね。
ぱっと見てAngularの魔法に見えたのが実はちゃんとしたTypeScriptだったので安心しました。
Angularはちゃんとルールを守る優等生。
publicも、protectedも同様に使える
private
のみならず、public
とprotected
で同様な記述法ができます。
public
class MyObject {
constructor(public name: string) {}
}
const obj = new MyObject("austin");
console.log(obj.name);
protected
class MyObject {
constructor(protected name: string) {}
}
class ExtendedObject extends MyObject {
get objName(): string {
return this.name;
}
}
const obj = new ExtendedObject("austin");
console.log(obj.objName);
console.log(obj.name); // TS Error
まとめ
以上、クラス構文のconstructor
メソッドでクラス・インスタンス変数を定義する速記法を紹介しました。
使うかどうかはいいとして、見た時に、「こういうことをやっているのだな」とわかればいいのかなと思います。
冗長なコードは必ずしも悪いコードではありません。
見てすぐにわかるようなコードが何よりもいいコードであるのです。
なので、筆者としてはこの手記法を推奨するというよりは、プロジェクトによって最もわかりやすい書き方を優先するべきだと考えています。
脱線ですが、パフォーマンスにこだわって読みやすさを犠牲にするスタイルは世の中にあります。いわゆる パフォーマンス至上主義 という考え方です。
筆者は真っ向からその考え方は間違っていると思います。
例えループが一つ増えたとしても、それによってわかりやすく書けるのであれば、ループを一つ増やしましょう。
(但し、ループの中のループ、いわゆるnested loop
は避けましょう!)
数ヶ月後の、そのコードを書いた自分が、感謝してくれますよ。数ヶ月後の自分を思いやりましょう。