現在の反復中に無名関数を生成する必要があります。次の手順で修正する必要があります。
// note these are actual addresses in the real page
var addresses = new Array( "addr 1", "addr 2", "addr 3", "addr 4" );
for (var i = 0; i < addresses.length; i++) {
geocoder.getLatLng(addresses[i], function (current) {
return function(point) {
if (point) {
var marker = new GMarker(point);
map.addOverlay(marker);
map.setCenter(point, 13);
GEvent.addListener(marker, "click", function() {
// here, i=4
marker.openInfoWindowHtml("Address: <b>" + addresses[current] + "</b>");
});
}
}
}(i));
}
B// これらは実際のページ内の実際のアドレスであることに注意してください var addresses = new Array( "addr 1", "addr 2", "addr 3", "addr 4" );
for (var i = 0; i < addresses.length; i++) { geocoder.getLatLng(addresses[i], function(point) { if (point) { var marker = new GMarker(point); map.addOverlay(marker) ; map.setCenter(点, 13);
GEvent.addListener(marker, "click", function() {
// here, i=4
marker.openInfoWindowHtml("Address: <b>" + addresses[i] + "</b>");
});
}
});
}
さらなる明確化
Google が提供
するgetLatLng
メソッドは、ajax 呼び出しを使用して、特定の住所の緯度と経度を取得します。これは非同期呼び出しであり、現在のスレッドの一部ではないため、ajax 要求の完了時に呼び出されるコールバック関数が必要です。これは、関数の 2 番目のパラメーターとして指定する無名関数です。
ここで、ajax リクエストが作成されている間、コードは引き続き実行され、i
ループが配列を反復するたびに の値が増加します。最初の ajax 呼び出しが戻るまでに、ループはすでにアドレス配列の長さ (4) まで増加しているため、コールバック関数が実行i
されると、ループによって増加した後にスコープ内の変数を取得しています。
私が書いた修正により、単一の引数を取り、変数を変数に置き換えcurrent
た前の匿名関数を返す匿名関数を作成しています。この関数は、ループの次の繰り返しの前に、最初のパラメーターとして変数を使用してすぐに呼び出されます。これにより、関数が呼び出されたときに の現在の値が変数に格納されるクロージャーが作成されます。後で変数を参照すると、格納されている の値が取得されます。i
current
i
i
current
current
i
私はこれらのことを説明するのがあまり得意ではありません。おそらく、私の理解が js Gods ほどよくないからです。javascript クロージャに関する詳細情報を読むことをお勧めします。