Задать вопрос
@Alex_87

Задача по замыканиям. Армия функции?

Добрый день! Помочь пояснить задачу, указанную на сайте: https://learn.javascript.ru/closures-usage (Армия функции) Столкнулся с проблемой понимания работы кода:
function makeArmy() {

  var shooters = [];

  for (var i = 0; i < 10; i++) {
    var shooter = function() { // функция-стрелок
      alert( i ); // выводит свой номер
    };
    shooters.push(shooter);
  }

  return shooters;
}

var army = makeArmy();

army[0](); // стрелок выводит 10, а должен 0
army[5](); // стрелок выводит 10...
// .. все стрелки выводят 10 вместо 0,1,2...9


В решении, в пункте "Почему ошибка" сказано: К моменту вызова army[0](), функция makeArmy уже закончила работу. Цикл завершился, последнее значение было i=10 ?
Отсюда и первый вопрос.
1) Функция makeArmy, закончила работы на этой строчки, я правильно понял? var army = makeArmy(); То есть, переменная army не только присвоила функцию но и отработала её?
2) Почему при вызове army[0]() и army[5](); не вызываются соответствующие элементы? Ведь, когда я вызвал console.log(army) мне вышел массив функции.
5c6a82c4e53ed508191822.png
Тогда почему я не могу обратиться к элементам этого массива?
3) Я не смог понять решение этой задачи. Хоть там их и 3) Помогите в коротко объяснить.
....
Задача - Фильтрация через функцию
https://codepen.io/Alexei_87/pen/vbjrpm?editors=0010
Вопрос описан в самом коде, в комментарии ниже!
  • Вопрос задан
  • 1087 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
VoidVolker
@VoidVolker Куратор тега JavaScript
Dark side eye. А у нас печеньки! А у вас?
После завершения работы функции makeArmy, значение переменной i остается равным 10. Соответственно, все функции в массиве будут выводить текущее значение этой переменной, а не то значение, которое было во время создания функции.
Для более позднего использования любого результата или значения/счетчик, существующего только во время работы цикла, следует создать еще одну переменную:
function makeArmy() {

  var shooters = [];

  for (var i = 0; i < 10; i++) {
    var shooter = (function(index){ // Вот тут создается еще одна переменная со значением счетчика
        return function() { // функция-стрелок  // Возвращаем функцию, которая использует уже не привязанную к счетчику отдельную переменную
            console.log(index); // выводит свой номер
        };
    })(i); // Передаем текущее значение счетчика в новую функцию, вызывая её
    shooters.push(shooter);
  }

  return shooters;
}

var army = makeArmy();
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы