TypeScriptとthisのおさらい

今回は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開発において扱いに悩む事があります。基礎的な内容でしたが、皆さんのおさらいのきっかけになれば幸いです。



Author
Yutaka Hirayama


Leave a Reply

Popular Posts