Question

I have this code:

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

and sometimes, randomly, I get an error this.units[i] is undefined.

Anybody got any idea how this is possible?

Was it helpful?

Solution

Pointy briefly touched upon the probable cause of the issue in his answer and that is that this.units[i] could be null. If you try and access a property on a null value you will get an "is null or not an object" error. In your example this is thrown by the attempt to access this.units[i].x in the if statement. The safest thing to do is to check and see if it's a null value first:

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 
}

You should also check out the other points of his answer, most importantly that for...in loops aren't ideal for arrays.

OTHER TIPS

The loop notation

for (var i in this.units)

gives you the attributes that are defined in the "units" object. Some of those may not have a value, for example if somewhere something had done:

this.units.balloon = null;

Iterating through object properties with "in" loops is pretty risky, unless you really know what's going on with your objects. If your object is actually an array, then you definitely don't want to do it - you should use numeric indexes and a plain loop with a numeric variable. (Even then, there might be null entries!)

MY Bad: I thought this question was in python!

You are probably doing something like:

del this.units[i]

somewhere in your code or altering your collection in some way. This is a No-No during iteration.

First of all, if your iteration is over an object, don't use "i" as the iteration variable, use prop or key to make it clear that you're iterating properties, not indexes.

Second, it sounds like you can simply debug and find out what element in your object is empty. Without the full code, it's hard to help you. I think the problem is that you are deleting by doing

obj.myProp = null;

Which means that a for in loop will still iterate over that property. However, if you use

delete obj.myProp;

myProp will not be iterated in a for in loop.

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

You're trying to index this.units using an element from this.units. Use a for loop (shown above) instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top