-2

私はこれの結果が10であることを知っています:

var es = [];
for (var i = 0; i < 10; i++) {
  es[i] = function () {
    console.log(i);
  };
}
es[6]();

es[0] - es[9] の任意の数はまだ 10 ですが、なぜですか?

4

4 に答える 4

5

ループの後i10. 関数は の参照を出力しますi

于 2013-09-04T19:48:15.257 に答える
3

作成されるのは整数オブジェクトのみです。これらconsole.log(i)はすべてメモリ内の同じオブジェクトを参照しています。i唯一の - の値はiもちろん、ループの最後で 10 です。

行がクロージャーを作成することに注意してくださいconsole.log(i)。これは、特に、によって参照される変数への新しい参照を作成していないことを意味しますi。同じ参考書です。

この分析を行う良い方法は、コード内で新しい実変数が作成された回数を追跡し続けることです。C や C++ などでプログラミングしたことがあれば、整数が 4 バイトまたは 8 バイトのメモリを必要とすることをご存知でしょう。線for(var i = 0;は、1 つのオブジェクトを作成するものと考えることができます。一つだけです。クロージャーはそれを行わないため、関数内では別のオブジェクトを作成するものは何もありません。

于 2013-09-04T19:48:10.153 に答える
2

これは、 を実行するconsole.log(i)までiに、ループが終了して変更されたためです。

より正確には、ループは条件が false の場合、つまり is の場合に停止forします。その後、10個の同一の関数があり、すべて同じ外部定義変数を使用しています。i < 10i10i

この古典的な閉鎖のトリックを使用して修正できます。

var es = [];
for (var i = 0; i < 10; i++) {
   (function(j){
     es[j] = function () {
       console.log(j);
     };
   })(i);
}
es[6]();

jこのコードが行うことは、スコープが無名関数呼び出しである新しい変数 を作成することです。iこれは、関数が呼び出されたとき (つまり、が呼び出されたときではなくループ中に)の値を保存する方法es[6]です。

于 2013-09-04T19:48:47.247 に答える
1

iループを参照しているため10、つまり、console.log(i) を実行しているときです。i の値が 10 に変更されました。

于 2013-09-04T19:48:40.373 に答える