【问题标题】:Array Error in Javascript: Uncaught TypeError: Cannot read property 'x' of undefinedJavascript 中的数组错误:未捕获的 TypeError:无法读取未定义的属性“x”
【发布时间】:2019-10-24 07:45:22
【问题描述】:

我在 newEntry.x 部分遇到“Uncaught TypeError: Cannot read property 'x' of undefined”。我不确定为什么它不会读取 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 的数组,但它只返回“未捕获的类型错误:无法读取未定义的属性 'x'。”

【问题讨论】:

    标签: javascript arrays for-loop


    【解决方案1】:

    看起来您正在尝试迭代一个比您拥有的数组更长的数组,因此您尝试在未定义的数组索引上设置 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

    【讨论】:

      【解决方案2】:

      由于边界检查不正确,您将离开数组的末尾:i &lt; (concordiaLogo.length-1) * 2。让我们称数组长度为“L1” 当您到达具有偶数个元素的数组的末尾时,i 将是L1 - 2。在中点拼接会导致数组长度比原来的长度(L1 + 1)大1。

      您的测试解析为i &lt; (L1 + 1) - 1,因此i &lt; L1 - 但我们知道iL1 - 2,因此测试将评估为真,并且循环将通过将i 增加2 来继续。 i 现在是 L1。不幸的是,您的代码确实如此:concordiaLogo[i].x + concordiaLogo[i+1].xi + 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)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-16
        • 2020-05-16
        • 2015-12-10
        • 2015-06-13
        • 1970-01-01
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多