0

私はJavaScriptで遊んでいますが、よくわからないことがあります。私はここにこのコードを持っています:

$.getJSON('data.json', function(obj) {

    for( var p in obj.List )
    {               
        datas['id'] = obj.List[p].ListingId;
        datas['area'] = area;

        //console.log(datas);

        var geocoder = new google.maps.Geocoder();              
        geocoder.geocode( { 'address': datas['area'] }, function(results,status)
        {

            if(status == google.maps.GeocoderStatus.OK)
            {
                var latlng = new google.maps.LatLng(results[0].geometry.location.Ya, results[0].geometry.location.Za);

                datas['latlng'] = latlng;

                //console.log(datas);                       

            }                               
        });
     }      
});

では、forループが3回実行されたとします。最初の「console.log(datas)」行のコメントを外してページを実行すると、コンソールに、独自の「id」と「area」を持つ3つの「datas」オブジェクトが表示されます。ジオコードコールバックの最初の「console.log(datas)」にコメントし、2番目の「console.log(datas)」のコメントを外すと、コードを実行すると、3つの「datas」オブジェクトすべてが「 id "、" area "、および"latlng"。私は3つの「データ」オブジェクトがそれら自身のlatlngsで異なるだろうと思っていましたが。

何か案は?

4

3 に答える 3

1

これはスコープの問題だと思います。最後にconsole.log実行されるまでに、p変数はすでに最後のobjを参照します。p新しいスコープでキャプチャする必要があります。

for( var p in obj.List ) { 

  (function(p) {

    datas['id'] = obj.List[p].ListingId;
    datas['area'] = area;

    geocoder.geocode( { 'address': datas['area'] }, function(results,status) {
      ...
    });

  }(p));

}
于 2012-11-22T21:39:24.323 に答える
1

関数に渡す関数はいつgeocoder.geocode実行されますか?すぐに実行されていない場合は、ジオコード関数が実行される前に、forループが3回すべて実行されます。これは、ループの最後の反復に設定されていることを意味しdatas['id']ますdatas['area']...この場合、ジオコード関数のクロージャー内のデータ配列をキャプチャする必要があります。

その場合、次のようなものが必要になります。

$.getJSON('data.json', function(obj) {

    for( var p in obj.List )
    {               
        datas['id'] = obj.List[p].ListingId;
        datas['area'] = area;

        //console.log(datas);

        var geocoder = new google.maps.Geocoder();              
        geocoder.geocode( { 'address': datas['area'] }, function(datas){ return function(results,status)
        {

            if(status == google.maps.GeocoderStatus.OK)
            {
                var latlng = new google.maps.LatLng(results[0].geometry.location.Ya, results[0].geometry.location.Za);

                datas['latlng'] = latlng;

                //console.log(datas);                       

            }                               
        }}(datas));
     }      
});

これにより、無名関数で使用されるデータ変数がforループによって更新されるのを防ぎます。

于 2012-11-22T21:51:40.593 に答える
0

データはグローバル配列として宣言する必要があると思いますか?ありますか?

于 2012-11-22T21:38:31.800 に答える