今回はAltJsとして弊社がよく利用するTypeScriptにおけるthisについておさらいします。
基本的にはJavaScriptと変わらない、、、のですが。
TypeScriptとJavaScriptの違いとして、関数の定義方法によるところがあります。
- アロー関数式
- ()=>{}
- ラムダ [lambda]式でも通じるかと思います。
- 当記事では「ラムダ式」と記載します。
- 従来function式
- function(){}
それぞれJavaScriptのfunctionと同じように使えます。
このラムダ式ですが、略記以外に重要なポイントがあります。
TypeScriptのラムダ式ではthisの扱いが異なるという所です。(ハンドブック参照)
確認していきましょう。
まず以下のサンプルを見て下さい。
sayLambda, sayFunc 両方共”Hello, World!”をコンソールに出力してくれます。簡単ですね。ただちょっと生成されたJavaScriptが異なります。
お気付きになりましたか?
ここでsayLambdaの方は、this が _this に置き換わっています。
この機能が無い場合、以下のようなパターンで sayFunc が undefined と出力してしまいます。
JavaScript側を確認すれば理由は明白ですね。ラムダ式を使った場合に、定義時のスコープを _this 変数にとりおいてくれて、thisを_thisに置き換えてくれるという仕様のおかげです。
ただ、気をつけることとして、ここに記述した定義方式ではクラスを継承した時に super で呼び出す事ができません。
(コンパイル結果は長いので割愛します。 Playground などでお試し下さい)
このパターンだと saySuper の出力は undefinedになってしまいます。
ここらへんは適宜メソッド定義の仕方を変えるか、thisを他の方法で確定させるか考慮が必要になってきます。
解決方法としては以下のようなパターンが考えられます。
こちらの例ではラムダを使った関数を返却するようにしています。コンパイルすると”thisをclosureで参照した関数を取得するメソッド”ということになるので。この場合は_saySuper をコールしても Hello, World! が出力できるのが確認できます。
TypeScriptでも、thisに苦しめられるあたり、JavaScript開発は一筋縄では行きませんね。
もう少し深堀りしたかったのですがここらへんで一旦、本記事は終わりになります。
何気なく使ってる「this」ですが、私は未だにJavaScript開発において扱いに悩む事があります。基礎的な内容でしたが、皆さんのおさらいのきっかけになれば幸いです。