Iterating over jQuery $(this).attr('class').split(" ") gives odd results

12,732

Solution 1

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

Solution 2

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);
});

Solution 3

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

Solution 4

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];
  }
}
Share:
12,732
Sam Starling
Author by

Sam Starling

Updated on June 05, 2022

Comments

  • Sam Starling
    Sam Starling almost 2 years

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

  • gblazex
    gblazex almost 14 years
  • Matthew Flaschen
    Matthew Flaschen almost 14 years
    Also note that for..in is not guaranteed to access the indices in numeric order (see MDC)
  • gblazex
    gblazex almost 14 years
    true, fortunately it's not an issue here
  • jAndy
    jAndy almost 14 years
    ecmascript 5 will also support Array.forEach() natively,
  • Anders
    Anders almost 14 years
    Or if you want even faster, use a negative while loop.
  • gblazex
    gblazex almost 14 years
    that's one more line of code, for almost no benefit. The real issue here is readability. This form does well on every field.
  • Sam Starling
    Sam Starling almost 14 years
    Thanks meder, that's exactly what I was looking for. Now I know!
  • Cheran Shunmugavel
    Cheran Shunmugavel about 12 years
    The i in this check is because JavaScript arrays are sparse. It's not necessarily true that every integer from 0 to length is actually an element of the array.