質問

この質問にはすでに答えがあります:

これは私が実行しようとしているものの簡略版です:

for (var i = 0; i < results.length; i++) {
    marker = results[i];
    google.maps.event.addListener(marker, 'click', function() { 
        change_selection(i);
    }); 
}

しかし、すべてのリスナーがresults.lengthの値(forループが終了したときの値)を使用していることがわかりました。追加時に i への参照ではなく i の値を使用するようにリスナーを追加するにはどうすればよいですか?

役に立ちましたか?

解決

最近のブラウザでは、あなたはブロックスコープ変数を作成するletまたはconstキーワードを使用することができます:

for (let i = 0; i < results.length; i++) {
  let marker = results[i];
  google.maps.event.addListener(marker, 'click', () => change_selection(i));
}
<時間>

古いブラウザでは、関数のパラメータとして渡すことで、現在の状態で変数を保存し、別のスコープを作成する必要があります:

for (var i = 0; i < results.length; i++) {
  (function (i) {
    marker = results[i];
    google.maps.event.addListener(marker, 'click', function() { 
      change_selection(i);
    }); 
  })(i);
}
匿名関数を作成し、最初の引数として変数でそれを呼び出すことによって、あなたが関数に値による受け渡しと閉鎖を作成しています。

他のヒント

と同様に閉鎖、あなたはfunction.bindを使用することができます

google.maps.event.addListener(marker, 'click', change_selection.bind(null, i));

は呼び出された関数の引数としてiの値を渡します。 (nullは、あなたがこのような場合には必要ありませんthisを、結合のためである。)

function.bindはプロトタイプフレームワークによって導入されたとのECMAScript第5版で標準化されています。すべてのサポートそれをネイティブのブラウザまで、あなたはクロージャを使用して独自のfunction.bindのサポートを追加することができます:

if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        var args= Array.prototype.slice.call(arguments, 1);
        return function() {
            return that.apply(owner,
                args.length===0? arguments : arguments.length===0? args :
                args.concat(Array.prototype.slice.call(arguments, 0))
            );
        };
    };
}

クロージャ:

for (var i = 0, l= results.length; i < l; i++) {
    marker = results[i];
    (function(index){
        google.maps.event.addListener(marker, 'click', function() { 
            change_selection(index);
        }); 
    })(i);
}

編集、2013:これらは現在、一般的に「 IIFE

あなたはクロージャで巻き取ります。 <ストライキ> ここで閉鎖とどのように彼らと仕事への記事です。ページ上の実施例5をチェックしてください。それはあなたがしているに対処するシナリオです。

EDIT:四年後に、リンクが死んでいます。上記問題の根本は、(具体的にformarker = results[i]ループ形の閉鎖ということです。 markeraddEventListenerに渡されるとして、あなたはクロージャの副作用を参照してください。それが最終的に最後の反復後に閉鎖を経由して「保存」だ前に、共有「環境」は、ループの各反復で更新されます。 MDNは非常によくこれを説明しています。

for (var i = 0; i < results.length; i++) {
    marker = results[i];
    google.maps.event.addListener(marker, 'click', (function(i) {
        return function(){
            change_selection(i);
        }
    })(i)); 
}

私たちは、iの値を格納するために一時変数を定義することができると思います。

for (var i = 0; i < results.length; i++) {
 var marker = results[i];
 var j = i;
 google.maps.event.addListener(marker, 'click', function() { 
   change_selection(j);
 }); 
}

私はかかわらず、それをテストしていません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top