2

次のような js のセットがあるとします。

function a() {
this.meow = 0;
    var go = setTimeout(function() {
        this.parent.meow++;
    }, 500);
}

var woof = new a();

増加しないのはなぜですかwoof.meow、間違って参照している場合、なぜこれが機能するのですか:

(function() { 
   this.meow = 'woof'; 
   var go = setTimeout(function() {
      alert(this.parent.meow); 
   },500); 
   return true; 
})();

さらに紛らわしいのは、なぜこれがうまくいかないのかということです:

(function() { 
   this.meow = 0; 
   var go = setTimeout(function() {
      alert(this.parent.meow++); 
   },500); 
   return true; 
})();
4

2 に答える 2

5

parentJavaScript では特別な意味はありません (ブラウザでは意味があります)。タイムアウト関数では、インスタンスをthis参照するのではなく、オブジェクトを参照します。オブジェクトには というプロパティがありますが、その親には というプロパティがない可能性があります。その理由は、タイムアウト関数にあります。JavaScript では、関数が定義されている場所ではなく、関数が呼び出される方法によって完全に定義されているためです。以下のリンクを参照してください。awindowwindowparentmeowthiswindowthis

タイムアウト関数は への呼び出しのコンテキストに対するクロージャーであるためnew a、これを行うことができます。

function a() {
var self = this;

this.meow = 0;
    var go = setTimeout(function() {
        self.meow++;
    }, 500);
}

それが行うことは、 への呼び出し内でselfの値に呼び出される変数を設定することです。タイムアウト機能が閉じて使用できるようになります。thisaselfself.meow

間違って参照している場合、なぜこれが機能するのですか

引用したコードは機能しません(実例this) が、そのコードではオブジェクトを参照し、参照windowするような関数を呼び出すのは非常に簡単であるため、それに似たものが機能するのを見たと思います。そのため、最終的にはグローバル変数になります (設定したすべてのプロパティはグローバルです)。thiswindowmeowwindow

閉鎖とthis(私のブログで)の詳細:

于 2012-12-14T06:26:44.770 に答える
0

TJクラウダーは正しい、代替案:

function a() {
    var meow = 0;
    var go = setTimeout(function() {
        meow++;
    }, 500);
}
于 2012-12-14T06:29:17.317 に答える