Javascript 中的数组错误:未捕获的 TypeError:无法读取未定义的属性“x”

Posted

技术标签:

【中文标题】Javascript 中的数组错误:未捕获的 TypeError:无法读取未定义的属性“x”【英文标题】:Array Error in Javascript: Uncaught TypeError: Cannot read property 'x' of undefined 【发布时间】: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'。”

【问题讨论】:

【参考方案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)

【讨论】:

以上是关于Javascript 中的数组错误:未捕获的 TypeError:无法读取未定义的属性“x”的主要内容,如果未能解决你的问题,请参考以下文章

控制台显示未捕获的类型错误

电子中的奇怪错误。未捕获的异常:TypeError [ERR_INVALID_ARG_TYPE]:“路径”

未捕获的 TypeError:forEach 不是 javascript 函数中的函数错误

使用输入表单标记中的onclick属性的JavaScript未捕获引用错误

jQuery.browser:Javascript 未捕获的类型错误

未捕获的 ReferenceError:$ 未定义(PHP 中的 JavaScript/HTML)[重复]