1

私たちが知っているように、はグローバル スコープで実行されるため、 でsetTimeout正しく動作しません(そして今後も)thisthiswindow

しかし、私は簡単なテストを行いました:

function でラップするだけです:

var o={}
o.a=1;
o.m=function (){alert(this.a);}


setTimeout( 
  function (){
               o.m()  ;
             }

    ,100);

そして、それは警告を行い1ます。

ここで何か不足していますか?なぜこの解決策を示唆する答えがないのですか? 動作が異なりますか?

ps : ここで興味を持った人のために、失敗するデモがあります:

var o={}
o.a=1;
o.m=function (){alert(this.a);}


setTimeout( o.m   ,100); //undefined
4

3 に答える 3

3

これを行う適切な方法bind()は、無名関数のスコープにすることです。

var o = {};
o.a = 1;

setTimeout(function (){
    alert(this.a);
}.bind(o), 1000);

oあなたの答えは同じ結果を生成しますが、匿名関数内の from のスコープにアクセスしていません。グローバルオブジェクトの関数を呼び出しているだけoです。

への参照this.aは の範囲内からのものですo

于 2013-06-17T10:38:09.660 に答える
1

クロージャがありません。コールバック関数は、グローバルに宣言されていなくても、コールバックにアクセスできるoスコープで定義されている限り、 にアクセスできます。o

コールバック関数がまだそれを参照しているため、 JS は GC できませんo。したがって、スニペットは機能します

例:

(function()
{
    var scope = {};//an empty object
    setTimeout(function()
    {
        console.log(scope);
        console.log(typeof scope);
    },1000);
}());
console.log(scope);

ここで、undefinedログに記録されていることがわかり、(約) 1 秒後に、{}その後にobject表示が表示されます。
一方:

var foo = {bar: 'foobar',
           callback: function()
           {
               console.log(this);
           }
};
setTimeout(foo.callback, 1000);
console.log(foo.callback());

最初に によって参照されるオブジェクトをログに記録しますfooが、次に同じ関数オブジェクトがグローバル オブジェクトをログに記録します (正しく言うと)、関数参照はグローバル コンテキストで呼び出されるためです。これを回避する唯一の方法は、 を使用するbindか、別のクロージャを作成することです (ただし、それでは ATM に時間がかかりすぎます)。

ここ、JS のアドホック コンテキスト バインディングと参照解決について詳しく説明しまし

于 2013-06-17T10:41:58.317 に答える
0

「this」はスコープごとに定義が異なりますが、「o」はグローバルに定義しただけです。

于 2013-06-17T10:39:38.980 に答える