2017.3.30
2017.4.17

指定された時間経過後に処理を実行する(setTimeout)

指定された時間経過後に処理を実行する方法としてsetTimeout()を利用するのが一般的だと思いますが、JavaScriptでやっていた書き方だとTypeScriptでは問題があったのでメモしておきます。

間違ったコード

やりたかったのは、指定された時間経過後にコンポーネントが所持しているフラグ(exampleFlag)を切り替えて、template(HTML)上の要素の表示を切り替えるといった処理です。

TypeScript


setTimeout(function() {
  this.exampleFlag = false;
}, 500);

上記のコードをコンパイラに通してJavaScriptを生成すると、下記のようになります。


setTimeout(function () {
  this.exampleFlag = false;
}, 500);

見て分かるようになにも変わっていません。TypeScriptで記述したコードがそのまま出力されています。

この場合、exampleFlagの値を切り替えても画面に反映されません。理由は「this」の参照先が setTimeout() が呼び出されたコンポーネントではなく、windowオブジェクトに設定されてしまうためです。(javascriptのsetTimeout()で指定するfunctionへの引数とthis問題

正しいコード

TypeScript


setTimeout(() => {
  this.exampleFlag = false;
}, 500);

上記のコードをコンパイラに通してJavaScriptを生成すると、下記のようになります。


var _this = this;
setTimeout(function () {
    _this.exampleFlag = false;
}, 500);

間違ったコードで生成されたJavaScriptと比較すると、事前にコンポーネントの「this」をローカルの変数「_this」に格納しておいて、setTimeout()内でこの「_this」を呼び出すように変換されているのが分かります。

早めに気づいてよかったです。あと「this」の参照をコンパイラが自動で変換してくれるとは思っていなかったので、ちょっと感動しました。

Angular】関連記事