Почему в одном случае функция не сохраняет переменную, а в другом сохраняет

Рейтинг: 0Ответов: 1Опубликовано: 12.01.2023
function makeArmy() {
  let shooters = [];

  let i = 0;
  while (i < 10) {
    let shooter = function() { // функция shooter
      alert( i ); // должна выводить порядковый номер
    };
    shooters.push(shooter);
    i++;
  }

  return shooters;
}

let army = makeArmy();

army[0](); // у 0-го стрелка будет номер 10
army[5](); // и у 5-го стрелка тоже будет номер 10
// ... у всех стрелков будет номер 10, вместо 0, 1, 2, 3.
function makeArmy() {
  let shooters = [];

  let i = 0;
  while (i < 10) {
    let j = i;
    let shooter = function() { // функция shooter
      alert( j ); // должна выводить порядковый номер
    };
    shooters.push(shooter);
    i++;
  }

  return shooters;
}

let army = makeArmy();

army[0](); // 0
army[5](); // 5

Почему в первом случае переменная i не сохраняется, а во втором просто присваивая она сохраняется. Т.е while создаёт каждой функции свое другое лексическое окружение?

Ответы

▲ -2

Всё легко, в первым случае, вы дальше увеличиваете i, которая в итоге становиться 10-кой. А shooter до сих пор выводит i, а не текущее число. Можно увидеть это в подобном примере:

Во втором случае же, вы сохраняете текущее число в переменную, теперь получается что shooter, выводит так нужное число (то, которые вы сохранили в j).

Можно от этого избавиться использовав обычный for цикл:

function makeArmy() {
  let shooters = [];

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

  return shooters;
}

let army = makeArmy();

army[0](); // 0
army[5](); // 5