views:

69

answers:

3

Hello,

I've got a page where I'm trying to fetch arrays of classes for lots of divs which share a common class. For example:

<div class="common lorem ipsum"></div>
<div class="common dolor sit"></div>
<div class="common hello world"></div>

I want to fetch each common class div and get an Array of it's classes. At the moment, I'm doing it by using this bit of jQuery:

$('.common').each(function(index) {
  var classes = $(this).attr('class').split(" ");
  for(var i in classes) {
    alert(classes[i]);
  }
});

Looking at the first resulting classes variable gives this:

classes: Array (3)
0: "common"
1: "lorem"
2: "ipsum"
length: 3
__proto__: Array

The problem is that the for(var i in classes) seems to be iterating over the __proto__ Array and delving down into that as well - has anybody ever come across this before? I'm using the latest version of Chrome (6.0.453.1).

+7  A: 
for ( var i = 0, l = classes.length; i<l; ++i ) {
 alert( classes[i] );
}

Iterate through an array with a regular for loop, not a for...in otherwise it enumerates through the array's properties ( since its still an object and has other properties in addition to the elements inside ).

meder
+1 avoid gotchas :) http://stackoverflow.com/questions/3154215/what-are-the-most-common-causes-of-errors-in-javascript-and-how-to-fix-them/3154285#3154285
galambalazs
Also note that for..in is not guaranteed to access the indices in numeric order (see [MDC](https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for...in))
Matthew Flaschen
true, fortunately it's not an issue here
galambalazs
ecmascript 5 will also support `Array.forEach()` natively,
jAndy
Thanks meder, that's exactly what I was looking for. Now I know!
Sam Starling
+2  A: 

@meder answered your question just right, i've just wanted to add, that if the order of the enumeration is not important, you can always use this simplified form:

for ( var i = classes.length; i--; ) {
  alert( classes[i] );
}

It is shorter, and faster.

galambalazs
Or if you want even faster, use a negative while loop.
Anders
that's one more line of code, for almost **no benefit**. The real issue here is **readability**. This form does well on every field.
galambalazs
+1  A: 

To add to the other valid answers, since you're already using jQuery, you can take advantage of jQuery.each:

$.each(classes, function (i, class) {
    alert(class);
});
Ates Goral