-1

javascript のコンテキストとスコープについて理解できたと思いました。ある状況ではプロキシ/バインドが機能し、別の状況では機能しない理由がわかりません。誰か説明してください。

例 1: プロキシ (またはバインド) の動作:

function Cat(name){
    this.name = name;

    $("#cat").click(
        $.proxy(
            function(e){ this.meow(e); }
        , this)
    );

    this.meow = function(){ alert(this.name + "says meow"); }
}
var cat = new Cat();

例 2: プロキシとバインドが機能しない:

function Dog(breed){
    this.breed = breed;

    this.save = function(){
        var that = this;
        $.ajax({
            url: '/ajax/savedog.php', dataType: 'json',

            // This works?? Shouldn't scope be of .ajax()?
            data: this.breed, 

            // success: $.proxy(... // won't work? why?
            success: that.dogSaved, error: ajaxFail
        });
    };

    this.dogSaved = function(){ alert("Dog Saved"); }
}
var dog = new Dog();
4

1 に答える 1

1

「クリック」ハンドラにコピーthisしています。外でやってください。that

の値はthis、関数呼び出しごとに新しく設定されます。したがって、「クリック」ハンドラー内thisは犬ではなく、DOM 要素です。

JavaScript での評価の順序に注意することも重要です。関数へのパラメーターは、呼び出し環境のコンテキストで完全に評価されます。最初の例では、this渡されたの値はコンストラクター$.proxy()のコンテキスト内のパラメーターであるため、正しい値でCatあり、したがって正しくは cat です。$.ajaxただし、Dogコンストラクターでのへの呼び出しでは、への参照は、コンストラクターではなくthis.breed「クリック」ハンドラーのコンテキストで評価されるため、正しい値を持ちません。上記のように の初期化を修正すると、「data」プロパティの値は次のようになります。that.breedthat

(@Musa が指摘しているように、Dogコンストラクターは構文的に正しくないことにも注意してください。これは単なる転記エラーだったと思います。)

編集—更新された質問で何をしようとしているのかわかりません$.proxy()が、次のように設定すると、その「成功」プロパティが機能するはずです。

   success: $.proxy(that.dogSaved, that),

の最初の引数$.proxy()は呼び出される関数で、2 番目の引数は関数が呼び出されるときに必要な値ですthis。この場合、それを犬オブジェクトへの保存された参照にする必要があります。ただし、「保存」関数がthis犬に設定されて呼び出された場合にのみ機能することに注意してください。つまり、どこかでこれを行う場合:

   var fido = new Dog();
   fido.save();

その後、物事はうまくいくはずです。ただし、犬への参照ではないような何らかの方法でその「保存」機能を何らかの方法で使用すると、機能しthisません。繰り返しますが、"Dog" コンストラクターで "that" の宣言を "save" ではなくコンストラクター スコープに移動した場合、"save" がどのように呼び出されるかは問題ではありませ。犬オブジェクトへの参照。

于 2012-10-07T14:57:14.763 に答える