对于迭代,元素未定义

问题描述 投票:0回答:6

我有这个代码:

for(var i in this.units)
 {
 if(this.units[i].x==att.x && this.units[i].y==att.y){}
 //... some more code
 }

有时,我会随机收到错误 this.units[i] is undefined。

有人知道这怎么可能吗?

javascript foreach undefined
6个回答
2
投票

循环表示法

for (var i in this.units)

为您提供“单位”对象中定义的属性。其中一些可能没有价值,例如,如果某处做了某件事:

this.units.balloon = null;

使用“in”循环迭代对象属性是相当危险的,除非你真的知道你的对象发生了什么。如果您的对象实际上是一个数组,那么您肯定不想这样做 - 您应该使用数字索引和带有数字变量的普通循环。 (即使如此,也可能存在空条目!)


1
投票

Pointy 在他的回答中简短地谈到了问题的可能原因,那就是

this.units[i]
可能为空。 如果您尝试访问 null 值的属性,您将收到“is null or not an object”错误。 在您的示例中,这是由于尝试在 if 语句中访问
this.units[i].x
引发的。最安全的做法是首先检查它是否为空值:

for(var i in this.units) 
{ 
    if (this.units[i] === null)
        continue;

    if(this.units[i].x==att.x && this.units[i].y==att.y){} 
    //... some more code 
}

您还应该查看他的答案的其他要点,最重要的是

for...in
循环对于数组来说并不理想。


1
投票

我的坏处:我以为这个问题是用Python写的!

您可能正在做类似的事情:

del this.units[i]

在代码中的某个位置或以某种方式更改您的集合。这是迭代期间的禁忌。


1
投票

首先,如果你的迭代是在一个对象上,不要使用“i”作为迭代变量,使用 prop 或 key 来明确你正在迭代属性,而不是索引。

其次,听起来您可以简单地调试并找出对象中的哪个元素是空的。 没有完整的代码,很难为您提供帮助。我认为问题是你正在通过这样做删除

obj.myProp = null;

这意味着 for in 循环仍会迭代该属性。但是,如果您使用

delete obj.myProp;

myProp 不会在 for in 循环中迭代。


0
投票
for(var i = 0; i < this.units.length; i++){
    if(this.units[i].x==att.x && this.units[i].y==att.y){}
}

您正在尝试使用

this.units
中的元素来索引
this.units
。请改用 for 循环(如上所示)。


0
投票

如果 this.units 是可迭代的,则使用 for...of 循环

   for (const key of Object.keys(this.units)) {
        if (this.units[key].x === att.x && this.units[key].y === att.y) {
            
        }
    }

如果 this.units 是一个数组

for (const unit of this.units) {
    if (unit.x === att.x && unit.y === att.y) {
       
    }
}

如果 this.units 未定义或未正确初始化,for...in 循环将抛出错误


if (!Array.isArray(this.units)) {
    console.warn('this.units is not an array.');
}

如果某些索引未定义 this.units[i]

for (var i in this.units) {
    if (this.units[i] && this.units[i].x === att.x && this.units[i].y === att.y) {
       
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.