2

オブジェクト メソッドを引数として setTimeout に渡すと問題が発生します。ネストされた関数内で、このスコープを手動で設定する必要があることは知っていますが、関数オブジェクトを直接渡す場合、私の場合は this.counting. 匿名関数を最初の引数として宣言する必要は何ですか。 this.counting は既に関数です。

Mozillaは、setTimeout の最初の引数内で this.remind の代わりに function(msg) {self.remind(msg);} も使用します。

function Timer(count,start){
    this.count = count;
    this.start = start;

}

//below code works
Timer.prototype.counting = function(){
    var self = this;
    setTimeout(function(){self.counting();},this.start);
    console.log(this.count);
    this.count++;
};

//below code doesn't work
/*
Timer.prototype.counting = function(){
    setTimeout(this.counting,this.start);
    console.log(this.count);
    this.count++;
};
*/
var t1 = new Timer(0,1000);
t1.counting();
var t2 = new Timer(100,1000);
t2.counting();
4

1 に答える 1

4

の MDN ドキュメントにsetTimeoutは、それに関するセクション全体があり、読むことをお勧めします。


に渡すコールバック内では、クラスのインスタンスではなくsetTimeoutthisを参照します。window

関数が呼び出された場合、this.count(これは を参照window.count) になります。これは、グローバル変数undefinedがないためです。count後にNaN( undefined++is NaN) になります。オブジェクトのcountプロパティはまったく変更されません。

self.counting()関数をオブジェクト ( )のメソッドとして明示的に呼び出すことthisで、 がクラスのインスタンスを正しく参照していることを確認できます。

別の関数を使用する代わりに、.bind [MDN]を使用して同じことを実現できます。

setTimeout(this.counting.bind(this), this.start);

の詳細については、この MDN 記事をお読みくださいthis

于 2012-12-26T04:37:23.680 に答える