10

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).

Sam Starling
  • 5,298
  • 3
  • 35
  • 52

5 Answers5

17
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 omuraliev
  • 183,342
  • 71
  • 393
  • 434
4

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

$.each(classes, function (i, cls) {
    alert(cls);
});
Ates Goral
  • 137,716
  • 26
  • 137
  • 190
2

@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.

gblazex
  • 49,155
  • 12
  • 98
  • 91
  • 1
    Or if you want even faster, use a negative while loop. – Anders Jul 05 '10 at 17:44
  • that's one more line of code, for almost **no benefit**. The real issue here is **readability**. This form does well on every field. – gblazex Jul 05 '10 at 17:58
1

Adding to meder's answer...

There is a way of iterating over objects safely without being annoyed by the inherited properties of an object. hasOwnProperty() to the rescue:

for(var i in classes) {
  if (classes.hasOwnProperty(i)) {
    var safeValue = classes[i];
  }
}
CodeReaper
  • 5,988
  • 3
  • 35
  • 56
0

I've seen this used here.

I'm not sure what the (i in this) double-check against 0-n weeds out.

var thisp = arguments[1];
for (var i = 0, len = this.length; i < len; i++){
  if (i in this){
    fun.call(thisp, this[i], i, this); // fun(element,index,array)
  }
}
LoveAndCoding
  • 7,857
  • 2
  • 31
  • 55
Skews Me
  • 1
  • 1
  • 1
    The `i in this` check is because [JavaScript arrays are sparse](http://stackoverflow.com/questions/1510778/are-javascript-arrays-sparse). It's not necessarily true that every integer from 0 to `length` is actually an element of the array. – Cheran Shunmugavel Feb 05 '12 at 21:27