0

I have an object this.themeData something like this (console output shown)

Object
    Banner: Object
        property: "null"
        raw: "uploads/1/somefile.png"
        selector: "null"
        value: "../../uploads/1/somefile.png"
        __proto__: Object
    H1_FontSize: Object
    H2_FontColor: Object
    H2_FontSize: Object

and I loop through like this:

    for (attrName in this.themeData) {
        attrData = this.themeData[attrName];
        if (attrData.selector && attrData.value) {
            $(".SomeSelector").css(attrData.property, attrData.value);
        }
    }

This works, but I saw in a recent SO question that I shouldn't use for in. But how can I loop through if the indexes are not numeric values for(var i = 0; i<arr.length; i++) where this.themeData[i] doesn't exist ?

Community
  • 1
  • 1
ed209
  • 11,075
  • 19
  • 66
  • 82
  • It seems you did not read the whole answer in the other question... it thoroughly describes how to iterate over objects and what the gotchas are. Everything that is mentioned in these answers here (the use of `hasOwnProperty`) is explained in greater detail there as well. – Felix Kling Aug 31 '12 at 10:52

2 Answers2

2

It's fine to use for..in loops on Objects, you just need to filter them with a hasOwnProperty() check

for (attrName in this.themeData) {
    if (this.themeData.hasOwnProperty(attrName)) {
        attrData = this.themeData[attrName];
        if (attrData.selector && attrData.value) {
            $(".SomeSelector").css(attrData.property, attrData.value);
        }
    }
}
Lucas Green
  • 3,951
  • 22
  • 27
2

Using the for...in method is fine in my opinion, just be sure to check that the properties you're looking for aren't from somewhere up the prototype chain.

var foo = Object();
for(item in foo) {
  if(foo.hasOwnProperty(item) {
      alert(item); // The key
      alert(foo[item]); // The value.
  }
}

If you don't check hasOwnProperty, you'll end up with properties inherited from Object.

Aesthete
  • 18,622
  • 6
  • 36
  • 45