thisポインタは、コンテキストに応じて、次のいずれかを指すことができます。
- コンストラクター関数(前にある関数呼び出し
new)thisでは、新しく作成されたコンストラクターのインスタンスを指します。
- 関数がオブジェクトのメソッドとして呼び出されると(たとえば
obj.funct())this、関数内のポインターはオブジェクトを指します。
- 、または
thisを使用して、ポイントを明示的に設定できます。callapplybind
- 上記のいずれでもない場合、
thisポインタはデフォルトでグローバルオブジェクトを指します。ブラウザでは、これがwindowオブジェクトです。
あなたの場合、あなたはthis.start内部を呼んでいsetIntervalます。ここで、このダミーの実装について考えてみましょうsetInterval。
function setInterval(funct, delay) {
// native code
}
startと呼ばれていないことを理解することが重要this.startです。と呼ばれていfunctます。これは、次のようなことをするようなものです。
var funct = this.start;
funct();
これらの関数はどちらも通常は同じように実行されますが、小さな問題が1つありthisます。2番目のケースではポインターがグローバルオブジェクトを指しthis、最初のケースでは現在のオブジェクトを指します。
重要な違いは、this内部のポインタについて話していることですstart。検討:
this.start(); // this inside start points to this
var funct = this.start;
funct(); // this inside funct (start) point to window
これはバグではありません。これがJavaScriptの仕組みです。オブジェクトのメソッドとして関数を呼び出すと(上記の2番目のポイントを参照)、this関数内のポインターはそのオブジェクトを指します。
2番目のケースでfunctは、オブジェクトのメソッドとして呼び出されていないため、デフォルトで4番目のルールが適用されます。したがってthis、を指しwindowます。
この問題startは、現在のthisポインターにバインドしてからsetInterval、次のように渡すことで解決できます。
setInterval(this.start.bind(this), 200);
それでおしまい。この説明が、JavaScriptの素晴らしさについてもう少し理解するのに役立つことを願っています。