В настоящее время у вас есть переменная marker
, объявленная локальной для функции process
, но вы пытаетесь читать и записывать ее из других функций. В частности, addMarker
записывает в marker
без var
, что приводит к созданию случайной глобальной переменной. Между тем process
на самом деле не записывает в объявленный локальный marker
локальный код, поэтому он содержит undefined
, что приведет к срабатыванию кода Google Maps при его передаче.
(Такие инструменты, как jslint или ECMAScript 5 Strict Mode могут поймать случайные глобалы для вас. Примечание total
и i
также являются случайными глобалами.)
Похоже, addMarker
и addInfoname
были взломаны из тела process
без привязки переменных из process
, которые они оба использовали. Если бы они были включены в тело process
, это работало бы, но вы бы получили описанное поведение, в котором одно и то же значение marker
использовалось для каждого деления из-за проблемы замкнутого цикла.
Эта проблема возникает в языках с замыканиями и областью действия на уровне функций, включая JavaScript, Python и другие. В этих языках любые переменные, определенные в цикле for
или внутри него, являются локальными для содержащей функции, not перераспределяется каждый раз, когда вы обходите цикл. Поэтому, если вы делаете замыкание, ссылаясь на i
в первой итерации цикла, это та же самая переменная i
, на которую вы ссылаетесь во второй итерации цикла; каждый экземпляр функции имеет замыкание над одной и той же переменной i
, поэтому каждая функция будет видеть одно и то же значение. То же самое относится и к marker
.
Проблему с замкнутым циклом можно избежать, используя второе замыкание, которое сохраняет переменную цикла в аргументе, или, более чисто, используя механизм цикла на основе замыкания вместо C-подобного цикла for
. ECMAScript 5 предлагает array.forEach()
для этой цели, а jQuery предлагает $.each()
:
function process(json) {
$('#results').empty();
var gev= google.maps.event;
$.each(json.details, function(detaili, detail) {
var marker= addMarker(detail.lat, detail.lng);
$('#results').append($('<div>', {
text: detail.name,
mouseover: function() { gev.trigger(marker, 'mouseover'); },
mouseout: function() { gev.trigger(marker, 'mouseout'); }
}));
var infoname= new InfoName();
gev.addListener(marker, 'mouseover', function() { infoname.show(); });
gev.addListener(marker, 'mouseout', function() { infoname.hide(); });
infoname.open(map, marker);
});
}
function addMarker(lat, lng) {
return new google.maps.Marker({
map: map,
position: new google.maps.LatLng(lat, lng),
icon: new google.maps.MarkerImage(
'images/r.png',
new google.maps.Size(30, 30),
new google.maps.Point(0, 0),
new google.maps.Point(0, 30)
)
});
}