ИМХО. Простое решение должно выглядеть так
function makeArmy() {
var shooters = [];
for (var i = 0; i < 10; i++) {
var shooter = function(self_i) { // функция-стрелок
alert( self_i ); // выводит свой номер
};
shooter = shooter.bind(null, i);
shooters.push(shooter);
}
return shooters;
}
var army = makeArmy();
shooter = shooter.bind(null, i);
Метод bind доступный у функций, если объяснять простым языком - возвращает новую функцию, которая представляет из себя исходную функцию с приклеенным контекстом ( this внутри функции) - первый параметр (в данном случае null), и аргументами вызова - все последующие аргументы (у нас только i)
То есть shooter.bind(null, i) вернет функцию которая будет выполнять те же действия, что и исходная shooter, но будто первым параметром мы передали i.