В цикле for что-то реагирует как ошибка, когда в переменной, но когда не в переменной, это нормально

#javascript

Вопрос:

Поэтому я пытаюсь закодировать шахматную доску с теми ограниченными знаниями, которые у меня есть, и я на удивление преуспел. Но произошло что-то странное.

В цикле for я должен проверить все возможные ходы и сузить его (я знаю, что не самый эффективный, но я пытаюсь сделать это с как можно меньшей помощью). То, что я делаю, в основном проходит через пару массивов, чтобы попытаться это сделать.

И когда я это сделаю

   for (i = 0; i < legalMoves.length; i  ) {
    if (legalMoves[i] > 63 || legalMoves[i] < 0) {
      legalMoves.splice(i, 1)
      i--
    }
      console.log(squareInfo[legalMoves[i]][2]) // line to pay attention to
  }
 

Это работает идеально, как и ожидалось, но когда я это делаю

   for (i = 0; i < legalMoves.length; i  ) {
    lM = squareInfo[legalMoves[i]] // variable to pay attention to
    if (legalMoves[i] > 63 || legalMoves[i] < 0) {
      legalMoves.splice(i, 1)
      i--
    }
      console.log(lM[2]) // line to pay attention to
  }
 

Ошибка в том, что TypeError: Cannot read property '2' of undefined

Что действительно странно.

Следует отметить, что мои массивы не содержат неопределенных символов, и когда я запускаю их без переменной, они работают идеально и должным образом.

Знает ли кто-нибудь, почему это произойдет, поскольку возможность использовать переменную lM значительно упростила бы этот процесс.

Чтобы прояснить, возникает вопрос, почему одно и то же происходит, когда в переменной появляется ошибка.

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

1. Вы используете strict режим?

2. Вы изменяете i после инициализации lM , но в вашем предыдущем коде я был изменен перед входом в консоль. Поэтому, пожалуйста, инициализируйте lM приведенное ниже условие if.

3. Этот код также очень запутан из-за увеличения и уменьшения i в цикле, а также legalMoves изменения массива, который вы повторяете

4. @swapnilbandiwadekar Да, спасибо, что исправили это.

5. просто сделать это ниже if условия недостаточно, так как следующий legalMoves элемент также может находиться за пределами диапазона 1-63 . Целое lM = ... и то console.log должно быть в else порядке, чтобы быть уверенным.


Ответ №1:

Реальная проблема заключается в том, что ваш lM инициализируется с i помощью параметра, который имеет неправильное значение, так как это legalMoves[i] не принято.

Вы должны выполнять lM = ... свою часть только тогда, когда я пройду проверку.

  for (i = 0; i < legalMoves.length; i  ) {
    if (legalMoves[i] > 63 || legalMoves[i] < 0) {
      legalMoves.splice(i, 1)
      i--
    } else {
      lM = squareInfo[legalMoves[i]] // variable to pay attention to
      console.log(lM[2]) // line to pay attention to
    }
  }
 

Но лучшим подходом было бы удалить недопустимые значения из legalMoves массива перед циклом, чтобы вам не приходилось выполнять эти трюки в цикле.

 const onlyLegalMoves = legalMoves.filter((move) => (move >= 0 amp;amp; move <= 63));

for (i = 0; i < onlyLegalMoves.length; i  ) {
  const legalMove = onlyLegalMoves[i];
  console.log(squareInfo[legalMove][2]) // line to pay attention to
}
 

Наконец, если вы хотите найти только первый действительно правильный ход, вы можете просто использовать .find вместо всего цикла.

 const moveToUse = legalMoves.find( (move) => (move >= 0 amp;amp; move <= 63) );
console.log( squareInfo[moveToUse][2] );
 

Ответ №2:

Традис, то, как вы используете массив для хранения в отдельной переменной, является реальной проблемой. В Javascript, когда вы используете простую переменную, javascript фактически создает новое пространство памяти и назначает его этому пространству памяти.

  1. Но когда вы присваиваете массив или объект новой переменной javascript, она просто ссылается на эту конкретную переменную, а не создает копию этой переменной.
  2. Итак, когда вы присваиваете свой массив переменной IM , а затем удаляете i из вашего фактического массива. Итак, IM стало неопределенным, потому что этот конкретный индекс удаляется.
  3. Фактическая проблема заключается в вашем условии if, вы можете проверить это, прокомментировав условие if.
  4. Если вы действительно хотите использовать этот метод переменных, пожалуйста, используйте глубокое копирование, чтобы сделать фактическую копию вашего legalMoves массива.

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

1. Да, спасибо, я понял это в комментариях, и теперь это имеет гораздо больше смысла. Я ценю ваше время :)!!!

2. Другой способ, которым я могу это сделать, — просто вставить a continue; туда, где я сокращаю i . Не могли бы вы это предложить?

3. Нет lM , это не стало вдруг неопределенным, потому i что изменилось. Он lM уже инициализирован и не изменяется. Проблема legalMoves[i] squareInfo в том, что в первую очередь этого не существовало.

4. Да, так же было бы удаление несуществующего legalMoves[i] элемента, а затем его continue; исправление, чтобы он снова мог находиться наверху. Потому что после того, как я понял, что какой-то шаг неправильный, мне не нужно продолжать проверять, я могу просто продолжить.

5. @GabrielePetrioli О, я понимаю. Ты прав. Это один присвоенный индекс. В моем коде не должно быть никаких проблем. Моя вина