для итерации элемент не определен
-
18-09-2019 - |
Вопрос
У меня есть этот код:
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] не определено.
Кто-нибудь понял, как это возможно?
Решение
В своем ответе Пойнти кратко коснулся вероятной причины проблемы, а именно: this.units[i]
может быть нулевым.Если вы попытаетесь получить доступ к свойству с нулевым значением, вы получите ошибку «является нулевым или не является объектом».В вашем примере это вызывается попыткой доступа this.units[i].x
в операторе if.Самое безопасное — сначала проверить, является ли это значение нулевым:
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
циклы не идеальны для массивов.
Другие советы
Обозначение цикла
for (var i in this.units)
дает вам атрибуты, определенные в объекте «единицы».Некоторые из них могут не иметь значения, например, если где-то что-то произошло:
this.units.balloon = null;
Перебирать свойства объекта с помощью циклов «in» довольно рискованно, если только вы не Действительно знать, что происходит с вашими объектами.Если ваш объект на самом деле является массивом, то вам определенно не стоит этого делать — вам следует использовать числовые индексы и простой цикл с числовой переменной.(Даже тогда могут быть нулевые записи!)
Виноват:Я думал, что этот вопрос был на питоне!
Вероятно, вы делаете что-то вроде:
del this.units[i]
где-то в вашем коде или каким-то образом изменяя вашу коллекцию.Это «нет-нет» во время итерации.
Прежде всего, если ваша итерация выполняется над объектом, не используйте «i» в качестве переменной итерации, используйте prop или key, чтобы было ясно, что вы повторяете свойства, а не индексы.
Во-вторых, похоже, что вы можете просто выполнить отладку и выяснить, какой элемент вашего объекта пуст.Без полного кода вам трудно помочь.Я думаю, проблема в том, что вы удаляете, делая
obj.myProp = null;
Это означает, что цикл for in все равно будет перебирать это свойство.Однако, если вы используете
delete obj.myProp;
myProp не будет повторяться в цикле for in.
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 (показанный выше).