Итератор Javascript не будет работать, но жестко заданное число будет

#javascript #loops #google-maps-api-3

#javascript #циклы #google-maps-api-3

Вопрос:

Я пытаюсь создать динамические маркеры с помощью Google Maps api, и у меня возникают проблемы при использовании переменной, которая повторяется.

Я опустил код для генерации маркеров и карты, потому что, похоже, он работает нормально. Это код для генерации информационного окна.

Этот код выдает ошибку ‘this_marker_info[$ n]’ [undefined] не является объектом

 for(var $n = 0; $n < business.length; $n  ){
   google.maps.event.addListener(this_marker[$n], 'click', function() {
       this_marker_info[$n].open(map, this_marker[$n]);
   });      
}
  

Этот код работает

 for(var $n = 0; $n < business.length; $n  ){
   google.maps.event.addListener(this_marker[$n], 'click', function() {
       this_marker_info[0].open(map, this_marker[0]);
   });      
}
  

Все, что я сделал, это заменил $ n на число 0 во втором примере в строке, которая гласит «this_marker_info[$n].open(map, this_marker[$ n]);»

Любая помощь была бы оценена

Комментарии:

1. Возможно, this_marker_info массив разрежен (= в нем есть «дыры»)…

2. … подождите минутку. Вы выполняете итерацию business , но затем пытаетесь получить доступ к элементам this_marker и this_marker_info . Откуда вы знаете, что эти массивы такие же длинные, как business массив?

Ответ №1:

Это типичная проблема с закрытием. Ко времени this_marker_info[$n].open(map, this_marker[$n]); выполнения вы завершили цикл, и значение $n равно business.length .

Решение состоит в том, чтобы написать замыкание:

 for(var $n = 0; $n < business.length; $n  ){
    (function ($the_actual_n) {
        google.maps.event.addListener(this_marker[$the_actual_n], 'click', function() {
            this_marker_info[$the_actual_n].open(map, this_marker[$the_actual_n]);
        });
    }($n)); // <-- call this 'anonymous' function with $n
}
  

Ответ №2:

Использование Array.forEach() — хороший и аккуратный способ это исправить:

 business.forEach(function(item, $n) {
   google.maps.event.addListener(this_marker[$n], 'click', function() {
       this_marker_info[$n].open(map, this_marker[$n]);
   });      
}
  

Таким образом, содержащая функция никогда не увеличивается $n , поэтому она надежно сохранит свое исходное значение.

Для использования Array.forEach() в старых браузерах, смотрите это.

Комментарии:

1. forEach действительно позволяет обойти эту проблему, потому что под водой он выполняет закрытие за вас. Обычно это способ, либо используйте forEach, либо вашу собственную функцию отображения массива.