2020.1.24

setTimeoutを使用する際の注意点

setTimeoutを使う際、Vue.jsで定義した変数にアクセスしようとすると「this」が別のオブジェクトを参照していて、値の取得や設定したりするのにちょっと工夫が必要だったので、メモとして残しておきます。

問題のあるコード

setTimeoutの処理で問題のあるコードは以下の通り。


var app = new Vue({
  el: '#app',
  data: {
    message: "Hello World!!"
  },
  mounted:function () {
    setTimeout(function(){
      alert(this.message);
    }, 1000);
  }
});
</script>

動作確認はこちら

上記のコードを実行すると、alertで「undefined」が表示されてしまいます。

これはsetTimeout内で呼び出している「this」が別のオブジェクトを参照してしまっているのが原因です。

修正したコード

上記のような、setTimeout内の処理でもVue.jsのthisにアクセスしたい場合、以下のようにします。


var app = new Vue({
  el: '#app',
  data: {
    message: "Hello World!!"
  },
  mounted:function () {
    setTimeout(function(){
      alert(this.message);
    }.bind(this), 1000);
  }
});

動作確認はこちら

違いはsetTimeoutで呼び出している関数の最後に「.bind(this)」を追加している点。

こうすることでsetTimeout内でもVue.jsのオブジェクトにアクセスできるようになります。

また、これとは別に以下のような書き方も可能です。


var app = new Vue({
  el: '#app',
  data: {
    message: "Hello World!!"
  },
  mounted:function () {
    var _this = this;
    setTimeout(function(){
      alert(_this.message);
    }, 1000);
  }
});

最近まではこちらの書き方で対応していましたが、「.bind(this)」と書いた方がコードの量が減るので、今後はbindの方をメインで使っていこうと思います。

ちなみに今回はVue.jsとして取り上げましたが、他のフレームワークやライブラリでも同様なので、setTimeoutやsetIntervalを使う際は注意が必要です。

Vue.js】関連記事