views:

50

answers:

2

Ok I've been learning some of the more advanced aspects of Javascript and now trying to use this I'm stuck.

Here is my code:

function Data(){}

function init(state){
  var item;
  item=new Data();
  item.fieldrid=17;
  item.description='foo';
  state.push(item);
};


function findInState(state,fieldrid) {
    for (var item in state) {
        alert(item.fieldrid); //prints undefined
        if (item.fieldrid == fieldrid) {
            return item;
        }
    }
    return null;
}

var s=[];
init(s);
alert(s[0].fieldrid); //prints 17 (expected)
alert(findInState(s,17).fieldrid); //exception here. function returns null.

A running example is here at jsbin

Why does this not work? I would expect the alert in findInState to yield 17 but instead it yields undefined.

What am I doing wrong?

+3  A: 
for (var item in state)

You should not loop over an array using for..in.
It works as expected when using for (var i = 0; i < state.length; i++).

See https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for...in:

Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea.

deceze
Actually, you can loop over it, the `var item` then only holds the array index. You should then use `state[item]` instead of `item` in the remnant of the `for` block. Needless to say that this is indeed not the preferred way to loop over an array :)
BalusC
@BalusC Good point.
deceze
@balus so then what is "the preferred way"? Is there some short cut I'm missing other than the C style `for(;;)` syntax?
Earlz
@Earlz No, `for(;;)` *is* the preferred way.
deceze
Use `for(;;)`. The `for in` may return other properties than array index and the iteration order is arbitrary. You need to do additional checks. Also see the link in the answer, there's a whole paragraph at bottom of *Description* chapter.
BalusC
@Earlz: See also [this answer](http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/3010848#3010848) I've posted earlier for more details about why you should avoid `for-in` with array-like objects...
CMS
A: 

In

alert(item.fieldrid); //prints undefined

You need to access the array state[item] so before that line, prepend

item = state[item];

I think, that I'll do.