Javascript では、setTimeout および setInterval によって受け取られる最初のパラメータは文字列または関数です。オブジェクト内で setTimeout を使用してオブジェクトのメソッドの呼び出しを遅らせる場合は、
function obj() {
this.fn = function() {
alert("ok");
console.log(this);
setTimeout(this.fn, 1000);// this を直接使用して現在のオブジェクトを参照します
}
}
var o = new obj( );
o.fn();
そして、上記のコードが望ましい結果ではないことがわかりました。その理由は、setTimeout が window を指しているためです。は window.fn になり、 unfineed になるので、悲劇でした。したがって、問題の鍵は現在のオブジェクトの参照を取得することなので、次の 3 つのメソッドがあります
// メソッド 1:
function obj() {
this.fn = function() {
alert("ok" );
console.log(this );
setTimeout(this.fn.bind(this), 1000);//Function.prototype.bind を通じて現在のオブジェクトをバインドします
}
}
var o = new obj();
o.fn();
残念ながら、Function.prototype.bind メソッドは ES5 の新しい標準です。 . IEシリーズを試してみたところ、IE6~8ではサポートされておらず、使えるのはIE9のみでした。互換性を持たせたい場合は、単純にバインドをシミュレートする必要があります。以下のコードを見てください。
// メソッド 2:
function obj() {
this.fn = function() {
alert("ok"); (function(a,b){
return function(){
b.call(a);
}
})(this,this.fn), 1000);//関数をシミュレート.prototype.bind
}
}
var o = new obj();
o.fn();
まず現在のオブジェクトとオブジェクト メソッドを渡します。自己実行匿名関数。つまり、内部のパラメータ a と b はクロージャを返し、call メソッドを使用してこれを正しいポイントにポイントします。以下はより簡単な方法です。
//方法 3:
function obj() {
this.fn = function() {
var that = this;//現在のオブジェクトを保存します this
alert("ok"); setTimeout(function() {
that.fn();
}, 1000);//
}
} var o = new obj();
o.fn();
上記の 3 番目のメソッドの 2 つの重要な点は、現在のオブジェクトをエイリアスとして保存することと、取得することです。クロージャを介して現在のスコープを取得し、保存されたオブジェクトにアクセスします。オブジェクト メソッドに複数のネストされた関数や setTimeout、setInterval、その他のメソッドがある場合、これは失われます (つまり、これは現在のオブジェクトではなくウィンドウを指します)。 ) なので、var that = this を this が指す正しいスコープに保存すると、非常に実用的になります。