2

Javascript を使い始めたとき、外部イベント ハンドラー (タイマーなど) にオブジェクト内の関数への参照を渡すときに、オブジェクトthis.への参照に依存できないという難しい方法を学びました。代わりに、イベントを発生させたもののスコープを参照してください(タイマーの場合、それはwindow? だと思います)。

私が使用されている回避策は、自分自身へのプライベート/ローカル参照を作成し、それをコールバック ロジック内で使用することです。例えば:

function MyObject() { 
  var myThis = this;
  this.foo = true; 
  this.callback = function() { return myThis.foo; }
  this.interval = 30;
  setInterval(function () { myThis.callback(); }, myThis.interval);
}

これは、このような状況での標準的なコーディング プラクティスですか? そうでない場合、推奨される代替手段とその理由は何ですか (たとえば、上記の例のリスクは何ですか)?

4

3 に答える 3

4

現代の代替手段は、使用することFunction.prototype.bind()です...

setInterval(this.callback.bind(this), this.interval);

この.bind()メソッドは、指定した最初の引数(この場合はそれを囲む値)thisにバインドされた値を持つ関数を返します。this

thisネストされた関数の変数スコープ内から囲んでいる変数スコープの変数で目的の値を参照する必要がなくなり(質問に示されているように)、よりクリーンなコードが提供されます。


古い実装MDNは、ほとんどの場合に十分な互換性パッチを見つけることができます。


補足としてthis、JavaScript における の値の問題はスコープの問題ではなく、呼び出しコンテキストの問題です。

于 2012-04-06T01:25:22.700 に答える
3

簡単な回答: これは受け入れられている方法であり、私の知る限り欠点はありません。

長い(っぽい)答え: Prototype メソッドを操作してこれを行うことができます。 am not i amの答えを参照してください。

于 2012-04-06T01:27:29.740 に答える
1

一時的な「this」を使用せずに、クロージャを使用してバインドを使用せずにこれを行うことができます。

これは、実際にこれを行うための良い方法であるとは考えられていませんが、クロージャとバインディング コンテキストがどのように機能するかを示しています。function.prototype.bindこれが機能する理由を理解できれば、同じことを行うためのコーディング方法を理解できるはずです。

http://jsfiddle.net/WRJqF/

function MyObject() { 
    this.foo = true; 
    this.callback = function() { 
        // firebug
        console.log( this.foo); 
    };
    this.interval = 30;

    setTimeout((function (that) {
        return function() {
            that.callback();
       };
   }(this)), this.interval); 

}

これは、よく使用する 2 つの JavaScript の概念を使用しています。

1 - 自己実行機能。関数を括弧で囲むと、すぐに実行され、インラインで戻り値に効果的に置き換えられます。

(function add(x,y) {
    return x+y;
}(2,3)) 

になり6ます。

上記の例では、自己実行関数を使用しthis、パラメーターとして渡しました。これによりクロージャーが作成され、パラメーターの値 (that混乱させるために名前が付けられています) がその関数に永続的に関連付けられます。

2 - ファースト クラス オブジェクトとして機能します。this関数を返すことができる (または通常は他の値と同じように使用する) ことができるため、それを作成したスタック フレームの値にバインドされた自己実行関数から関数を返すことができます。したがって、自己実行機能は、事実上、

function() {
    that.callback();
};

…でも「あれ」は実は関数を作ったときに有効だった「これ」なのです!

それをすべて手に入れましたか??

于 2012-04-06T02:24:16.753 に答える