JavaScript for...in loop is having weird results

Go To StackoverFlow.com

1

I have the following object:

var r = {
    obj: $(this),
    children: $(this).children(),
    panes: $('.rotatorPane', $(this)),
    tagNames : [],
    captions: [],
    subcaptions: []     
};

$(this) refers to the following div:

<div class="myRotator">
    <div class="rotatorPane">

    </div>
    <div class="rotatorPane" id="pane3">

    </div>

    <img src="img/1.jpg" alt="pane 1" class="rotatorPane" data-caption="Lorem Ipsum" data-subcaption="Dolor sit amet" />

</div>

The problem I'm having is with the following for...in loop:

for(pane in r.panes){
    console.log(pane);
}

The output starts out as expected:

0
1
2

But then I get a bunch of method names as outputs:

length
prevObject
context
selector
constructor
init
jquery
size
toArray
get
...etc

Does anyone know why this is happening?

2012-04-04 19:07
by DC_


8

Don't use for ... in on things that are arrays, or array-like. Use a numeric index variable.

for (var i = 0; i < r.panes.length; ++i) {
  var pane = r.panes[i];
  // ...
}

The for ... in form is for iterating over the properties of an object — all of them. When you want to iterate through the indexed properties of an array (or, again, something that you're treating as an array), always use a numeric index.

In this case, the array-like object in question is a jQuery object, which has all sorts of properties besides the numerically-indexed properties.

2012-04-04 19:08
by Pointy
for in should only be using when retrieving all the keys for an object. For simple arrays whose prototype hasn't been modified, this mostly works, except that the order of iteration is not guaranteed (specially if you insert items in the middle of the array), so you should really never use it - Juan Mendes 2012-04-04 19:11
Well, yes, but personally I try to shy away from coding practices that "mostly work" when there's a simple alternative that always works. Also, for some code, you never know when its environment might change such that the Array prototype gets some additional iterable properties. Yes, there's the hasOwnProperty() test, but if you're having to go to all that trouble it seems like there's no point - Pointy 2012-04-04 19:14
If you read my comment, you'll see that my point was that even though there is a way that does work, you still shouldn't use it - Juan Mendes 2012-04-04 19:20
Oh OK well I see what you mean. I wasn't so much trying to criticize your statement (which is perfectly true) as to prevent anybody from thinking that for ... in is just "naughty" and not just a really bad idea :- - Pointy 2012-04-04 19:22


1

you should use the jQuery for each loop i think, as you probably cant use hasOwnProperty due to jquery adding its own methods and stuff to the object

2012-04-04 19:09
by NickSlash
Ads