для итерации элемент не определен - PullRequest
3 голосов
/ 09 марта 2010

У меня есть этот код:

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] не определено.

Кто-нибудь знает, как это возможно?

Ответы [ 5 ]

2 голосов
/ 09 марта 2010

Обозначение цикла

for (var i in this.units)

дает вам атрибуты, которые определены в объекте «unit». Некоторые из них могут не иметь значения, например, если где-то что-то было сделано:

this.units.balloon = null;

Перебор свойств объекта с помощью циклов "in" довольно рискован, если только вы не действительно знаете, что происходит с вашими объектами. Если ваш объект на самом деле является массивом, то вы определенно не хотите этого делать - вам следует использовать числовые индексы и простой цикл с числовой переменной. (Даже тогда могут быть нулевые записи!)

1 голос
/ 09 марта 2010

Прежде всего, если ваша итерация выполняется над объектом, не используйте «i» в качестве переменной итерации, используйте prop или key, чтобы было ясно, что вы итерируете свойства, а не индексы.

Во-вторых, похоже, что вы можете просто отладить и выяснить, какой элемент в вашем объекте пуст. Без полного кода вам трудно помочь. Я думаю, что проблема в том, что вы удаляете, делая

obj.myProp = null;

Это означает, что цикл for in все еще будет перебирать это свойство. Однако, если вы используете

delete obj.myProp;

myProp не будет повторяться в цикле for in.

1 голос
/ 09 марта 2010

МОЙ Плохой: я думал, что этот вопрос был на питоне!

Вы, вероятно, делаете что-то вроде:

del this.units[i]

где-то в вашем коде или как-то изменить вашу коллекцию. Это нет-нет во время итерации.

1 голос
/ 09 марта 2010

Пинти кратко коснулся возможной причины проблемы в своем ответе, и это то, что 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 не идеальны для массивов.

0 голосов
/ 09 марта 2010
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 (показан выше).

...