0

このコードは x is not defined を生成します

var myobj1 = 
{  
    x:9, 
    myfunction:function()
    {
        if(this === window) 
            alert("x is not Defined");
        else if (this === myobj1)
            alert(this.x);
        else
            alert("Error!");
    }
}

function test()
{
    setTimeout(myobj1.myfunction, 1000);
}

test();

このコードは出力として x=9 を生成しますが、

var myobj1 = 
{  
    x:9, 
    myfunction:function()
    {
        if(this === window) 
            alert("x is not Defined");
        else if (this === myobj1)
            alert(this.x);
        else
            alert("Error!");
    }
}

function test()
{
    setTimeout(function()
    {
        myobj1.myfunction()
    },  1000); 
}

「テストメソッドでコールバックメソッドが使用されていない場合、グローバルウィンドウオブジェクトが呼び出されている」理由と「この場合のコールバックメソッドの重要性」を誰かが説明できますか?

4

1 に答える 1

1

に渡すmyobj1.myfunctionsetTimeout()、関数参照のみが渡されました。オブジェクトへの接続はすべて失われます。 setTimeout()特定のオブジェクトのコンテキストで関数参照を呼び出す機能はありません。したがって、オブジェクトのコンテキストでメソッドを呼び出す独自の関数を渡すか.bind()、最新のブラウザーで同じことを行うことができます。

これを行う場合:

setTimeout(myobj1.myfunction, 1000);

JavaScript インタープリターは の関数参照を取得し、myobj1.myfunctionそれを に渡しsetTimeout()ます。これは、次と同じ結果を生成します。

var fn = myobj1.myfunction;
setTimeout(fn, 1000);

に渡されるとsetTimeout()、それは単なる関数参照でありfn()、オブジェクトのコンテキストではないように呼び出されます。オブジェクトのメソッドは、たまたま関数であるオブジェクトの「単なる」プロパティであることを思い出してください。関数内のthisポインターは、その呼び出し方法によって決まります。のようにオブジェクト コンテキストで呼び出されない場合、またはまたはでmyobj1.myfunction()明示的に呼び出されない場合、ポインターはオブジェクトになりません。.apply().call()this

発見したように、適切なオブジェクトのコンテキストでそれを呼び出す独自の小さなスタブ関数を作成できます。最新のブラウザーでは、次.bind()のように使用することもできます。

setTimeout(myobj1.myfunction.bind(myobj1), 1000);

これは基本的に、2 番目のコード例のスタブ関数と同じことを行います。

于 2013-04-07T17:12:26.687 に答える