1

JavaScriptのクロージャを理解しようとしています。サンプルコードを読みました:

function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
  return result;
}

var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
  fnlist[j]();
}

このコードは、「item3 undefined」アラートを 3 回出力します。5 行目の item 変数の "3" は理解できますが、5 行目の list[i] から "undefined" が出力される理由がわかりません。これもクロージャを使ってリスト変数にアクセスしていませんか?誰かがこれを説明できますか?

4

2 に答える 2

1

これらすべての変数にアクセスできます。問題は、次のループの i 変数です。

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }

i は参照によって渡され、ループごとに増加します。したがって、クロージャーをループに 3 回プッシュした後、i の値は 4 になり、すべてのコールバックは未定義の [1,2,3] (提供した配列) の 4 番目の要素を警告しようとします。

于 2012-10-07T10:39:59.760 に答える
0

最も簡単な説明は次のとおりです: ステートメントの周りではなく、関数の周りにクロージャーが作成されます!

それが何を意味するかを知るためにこれを試してください:

function createClosure(item, val) {
    return function() {alert(item + ' ' + val)};
}

function buildList(list) {
 var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( createClosure(item, list[i]) );
  }
  return result;
}
于 2012-10-07T11:06:38.807 に答える