9

JavaScript でコールバックを宣言するたびにオブジェクトのスコープを手動で設定しなければならないのはイライラしますが、これは現実です。[mycallback].apply をコールバックとして渡し、スコープ オブジェクトを引数として渡して、次のようにできるかどうか疑問に思いました。

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(f.apply, 1000, o);

私が知る限り、これはスコープとして o で f を呼び出す必要がありますが、代わりに Chrome は「Uncaught TypeError: Function.prototype.apply が [object DOMWindow] で呼び出されました。これはオブジェクトであり、関数ではありません」と表示されます。なぜこれが機能しないのですか?

4

3 に答える 3

5

同じ理由で、最初に「スコープを設定する」必要があります。関数のみapplyが に送信されsetTimeout、関数との関連付けfは失われます。したがって、Javascriptは、他の場合と同様にwindow、グローバル オブジェクト を に割り当てます。this

はネイティブ関数でありながら、何らかの点で特別でも魔法でもなく、変数applyの設定でユーザー定義関数と一貫した方法で動作することに注意してください。this

于 2011-03-25T00:13:12.323 に答える
4

@MooGooの答えは正しいですが、おそらくもっと説明が必要です。

このように関数を呼び出すapplyf

f.apply(ctx, args);

apply...次に、のコンテキストで実行していますf

しかし、次のapplyように関数への参照を渡すと、次のようになります。

setTimeout(f.apply, 1000, o);

...あなたがしているのはそれだけです:関数への参照を渡しますf.apply。これは、次の理由で渡すFunction.prototype.applyことと同じです。

console.log(f.apply === Function.prototype.apply); // true

への接続はすべてf失われwindow.setTimeoutます。のジェネリックapply関数への参照を受け取りFunction.prototypeます。これ以上何もない。コンテキストなし。

したがって、明示的なコンテキストが設定されていない他の場合と同様に、apply関数はwindowコンテキストオブジェクトとして呼び出されます。

于 2011-03-25T00:42:09.880 に答える
-1

これを試して:

var f = function() { console.log(this.x); };
var o = {x: 3};
setTimeout(function(){f.apply(o)}, 1000);

私のために働きます。

タイムアウトの設定には関数が必要です。ただし、apply は組み込み関数であり、その背後にあるネイティブ コードを確認できないため、「関数」オブジェクトとして機能しない可能性があります。

于 2011-03-25T00:11:58.447 に答える