Ошибка массива в Javascript: Uncaught TypeError: Невозможно прочитать свойство 'x' из неопределенного - PullRequest
0 голосов
/ 09 июня 2019

Я сталкиваюсь с "Uncaught TypeError: Невозможно прочитать свойство 'x' of undefined" в частях newEntry.x.Я не уверен, почему он не будет читать объекты внутри цикла for, поскольку в консоли он, кажется, распознает их значения.

Я пишу функцию, которая возвращает расширенный массив с серединамисмежные объекты.Это делается для определенного числа итераций, следовательно, для вложенного цикла for.Я не уверен, что делать, так как я пытался изменить цикл for и сплайс, но потерпел неудачу.

function newList(iterations) {

  for (let i = 0; i < iterations; i += 1) {
    let concordiaLogo = [
      { x: 12.5, y: -100 },
      { x: 12.5, y: -112.5 },
      { x: 12.5, y: -125 },
      { x: 68.75, y: -68.75 },
      { x: 125, y: -12.5 },
      { x: 112.5, y: -12.5 },
      { x: 100, y: -12.5 },
      { x: 100, y: 0 },
      { x: 100, y: 12.5 },
      { x: 112.5, y: 12.5 },
      { x: 125, y: 12.5 },
      { x: 68.75, y: 68.75 },
      { x: 12.5, y: 125 },
      { x: 12.5, y: 112.5 },
      { x: 12.5, y: 100 },
      { x: 0, y: 100 },
      { x: -12.5, y: 100 },
      { x: -12.5, y: 112.5 },
      { x: -12.5, y: 125 },
      { x: -68.75, y: 68.75 },
      { x: -125, y: 12.5 },
      { x: -112.5, y: 12.5 },
      { x: -100, y: 12.5 },
      { x: -100, y: 0 },
      { x: -100, y: -12.5 },
      { x: -112.5, y: -12.5},
      { x: -125, y: -12.5 },
      { x: -68.75, y: -68.75 },
      { x: -12.5, y: -125 },
      { x: -12.5, y: -112.5 },
      { x: -12.5, y: -100 },
      { x: 0, y: -100 }
    ]
    for (let i = 0; i < (concordiaLogo.length-1) * 2; i += 2) {
      let newEntry = { x: 0, y: 0 };
      newEntry.x = (concordiaLogo[i].x + concordiaLogo[i+1].x)/2;
      newEntry.y = (concordiaLogo[i].y + concordiaLogo[i+1].y)/2;
      concordiaLogo.splice(i + 1, 0, newEntry);
    }
  }
  return concordiaLogo;
}

При вводе 3 я ожидал массив 32 * 2** 3, но он просто возвращает «Uncaught TypeError: Невозможно прочитать свойство 'x' из неопределенного."

Ответы [ 2 ]

1 голос
/ 09 июня 2019

Похоже, вы пытаетесь перебрать массив длиннее, чем тот, который у вас есть, поэтому вы пытаетесь установить x для индекса массива, который не определен.

Здесь итерация пытается пройти (array.length - 1) * 2, что почти вдвое больше длины вашего массива:

    for (let i = 0; i < (concordiaLogo.length-1) * 2; i += 2) {
      let newEntry = { x: 0, y: 0 };
      newEntry.x = (concordiaLogo[i].x + concordiaLogo[i+1].x)/2;
      newEntry.y = (concordiaLogo[i].y + concordiaLogo[i+1].y)/2;
      concordiaLogo.splice(i + 1, 0, newEntry);
    }

Когда вы нажимаете на индекс, который больше длины массива, concordiaLoco[i] не определен, поэтому вы не можете получить к нему доступ x.

0 голосов
/ 09 июня 2019

Вы выходите из конца массива из-за неправильной проверки границ: i < (concordiaLogo.length-1) * 2. Давайте назовем длину массива «L1». Когда вы доберетесь до конца массива с четным числом элементов, i будет L1 - 2. Соединение в средней точке приведет к тому, что длина массива станет на 1 больше, чем старая длина (L1 + 1).

Ваш тест разрешается до i < (L1 + 1) - 1, поэтому i < L1 - но мы знаем, что i было L1 - 2, поэтому тест оценивается как true, и цикл будет продолжаться с увеличением i на 2. i сейчас L1. К сожалению, ваш код: concordiaLogo[i].x + concordiaLogo[i+1].x. i + 1 оценивается как L1 + 1, на единицу больше, чем самый высокий индекс в массиве. concordiaLogo[i+1] не определено.

Это решает проблему путем проверки длины массива относительно ожидаемой длины (не уверен, как вы получили 32 * 2 ** 3, результат увеличивает длину массива на длину массива - 1):

function newList(iterations) {

  let concordiaLogo = [
    { x: 12.5, y: -100 },
    { x: 12.5, y: -112.5 },
    { x: 12.5, y: -125 },
    { x: 68.75, y: -68.75 },
    { x: 125, y: -12.5 },
    { x: 112.5, y: -12.5 },
    { x: 100, y: -12.5 },
    { x: 100, y: 0 },
    { x: 100, y: 12.5 },
    { x: 112.5, y: 12.5 },
    { x: 125, y: 12.5 },
    { x: 68.75, y: 68.75 },
    { x: 12.5, y: 125 },
    { x: 12.5, y: 112.5 },
    { x: 12.5, y: 100 },
    { x: 0, y: 100 },
    { x: -12.5, y: 100 },
    { x: -12.5, y: 112.5 },
    { x: -12.5, y: 125 },
    { x: -68.75, y: 68.75 },
    { x: -125, y: 12.5 },
    { x: -112.5, y: 12.5 },
    { x: -100, y: 12.5 },
    { x: -100, y: 0 },
    { x: -100, y: -12.5 },
    { x: -112.5, y: -12.5},
    { x: -125, y: -12.5 },
    { x: -68.75, y: -68.75 },
    { x: -12.5, y: -125 },
    { x: -12.5, y: -112.5 },
    { x: -12.5, y: -100 },
    { x: 0, y: -100 }
  ]
  for (let i = 0; i < iterations; i += 1) {
    var expected = concordiaLogo.length * 2 - 1
    for (let i = 0; concordiaLogo.length < expected; i += 2) {
      let newEntry = { x: 0, y: 0 };
      newEntry.x = (concordiaLogo[i].x + concordiaLogo[i+1].x)/2;
      newEntry.y = (concordiaLogo[i].y + concordiaLogo[i+1].y)/2;
      concordiaLogo.splice(i + 1, 0, newEntry);
    }
  }
  return concordiaLogo;
}

function init() {
  console.log(newList(1))
}

document.addEventListener("DOMContentLoaded", init)

Вот еще один способ сделать то же самое, но не требуя явного вычисления длины:

function newList(iterations) {

  let concordiaLogo = [
    { x: 12.5, y: -100 },
    { x: 12.5, y: -112.5 },
    { x: 12.5, y: -125 },
    { x: 68.75, y: -68.75 },
    { x: 125, y: -12.5 },
    { x: 112.5, y: -12.5 },
    { x: 100, y: -12.5 },
    { x: 100, y: 0 },
    { x: 100, y: 12.5 },
    { x: 112.5, y: 12.5 },
    { x: 125, y: 12.5 },
    { x: 68.75, y: 68.75 },
    { x: 12.5, y: 125 },
    { x: 12.5, y: 112.5 },
    { x: 12.5, y: 100 },
    { x: 0, y: 100 },
    { x: -12.5, y: 100 },
    { x: -12.5, y: 112.5 },
    { x: -12.5, y: 125 },
    { x: -68.75, y: 68.75 },
    { x: -125, y: 12.5 },
    { x: -112.5, y: 12.5 },
    { x: -100, y: 12.5 },
    { x: -100, y: 0 },
    { x: -100, y: -12.5 },
    { x: -112.5, y: -12.5},
    { x: -125, y: -12.5 },
    { x: -68.75, y: -68.75 },
    { x: -12.5, y: -125 },
    { x: -12.5, y: -112.5 },
    { x: -12.5, y: -100 },
    { x: 0, y: -100 }
  ]
  while (iterations--) {
    concordiaLogo = concordiaLogo.reduce(function(acc, val, idx, source) {
      acc.push(val) // push the current element
      if (idx < (source.length - 1)) { // if there's no more elements, just push the current element 
        // add the midpoint of this and the next element
        acc.push({
          x: (source[idx].x + source[idx+1].x)/2,
          y: (source[idx].y + source[idx+1].y)/2
        })
      }
      return acc
    }, [])
  }
  return concordiaLogo;
}

    function init() {
      console.log(newList(3).length)
    }

    document.addEventListener("DOMContentLoaded", init)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...