book
book copied to clipboard
「プライベートクラス機能」を執筆する
#242 でコンテンツ化するかを議論しましたが、賛成が多いのでコンテンツ化します。
タイトル
- 記事タイトル: プライベートクラス機能とハードプライベート (hard private)
- サイドバー: プライベートクラス機能
...
- 検索のために「ハードプライベート」もタイトルに入れていく
URLと場所
- URL: https://typescriptbook.jp/reference/object-oriented/class/private-class-features-hard-private
- 場所: 読んで学ぶ → オブジェクト指向 → クラス → プライベートクラス機能 (constructor shorthandの次のページとして。)
想定質問
- ソフトプライベート(アクセス修飾子の
private
)との違いは何? - ソフトプライベートとハードプライベートどっちを使ったほうが良い?
- なんでTypeScriptには2種類プライベートがあるの?
書いたほうが良いと思われるトピック
プライベートクラス機能とは
- フィールドやメソッドをプライベートにする機能
- JavaScript由来の機能であることを強調しておきたい
文法
-
#
で始まる識別子がハードプライベートになる。 - 参照するときも
#
込みで書く。 - プライベートフィールド
- プライベートメソッド
- プライベート静的フィールド
- プライベート静的メソッド
アクセスできる範囲
- 同じクラスの中からのみアクセス可
- 同じクラスなら異なるインスタンスのプライベートも見れる
- 子が親のプライベートは参照できない
- (JavaやPHPのprivateのように)リフレクションでこじ開けることもできない
private
修飾子との違い
- コンパイル後JavaScriptでの可視性: private → public同然、# → プライベート
- 継承での識別子の衝突: private → 親にprivateがあると、子で同じ名前が使えない
- インデックスアクセス型(indexed access types): private → 使える、# → 使えない
- コンストラクタショートハンド(constructor shorthand): private → 使える、# → 使えない
なぜハードプライベートと呼ばれるか
- ハードプライベート(hard private)はTypeScript固有の用語。
- privateがどうソフトなのか
- #がどうハードなのか?
TypeScriptにプライベートが2種類ある経緯
-
private
がもともとあった - 後からJavaScriptにプライベートクラス機能が加わった
- TypeScriptはJavaScriptの互換言語なので、それに追従して追加した
- 結果として2種類のプライベートができた
コンパイル後のJavaScript
- targetが○○のときは、そのまま#が使われる
- targetが○○以下のときは、WeakMapになる
- targetがes5のときは、#はコンパイルエラーになる
ハードプライベートを使うべきか?
- 現状のprivateを置き換える必要はない
- できるだけJavaScript標準に合わせたほうがいい。ECMAScriptの延長としての言語である「TypeScript」としての思想と一致している。
- ハードプライベートは「完全なカプセル化」であり、実行時もプライベートなのが約束される安心感がある。
- まだ新しい機能なので、使われているところは少ないが、新規コードから徐々にハードプライベートに寄せていくとよい
転用してもいい記事
TypeScript 4.3でプライベートクラスフィールド(#)が導入されました - Qiita
- suinの著作なので転用OK