views:

76

answers:

4

I normally use this pattern to iterate over object properties:

for(var property in object) {
   if(object.hasOwnProperty(property)) {
      ...
   }
}

I don't like this excessive indentation and recently it was pointed out to me that I could get rid of it by doing this:

for(var property in object) {
   if(!object.hasOwnProperty(property)) {
      continue;
   }

   ...
}

I like this because it doesn't introduce the extra level of indentation. Is this pattern alright, or are there better ways?

+4  A: 

I personally prefer:

for(var property in object) if(object.hasOwnProperty(property)) {
     ...
}

There is no extra level of indentation because for, if, etc. will take the next statement if you leave out the curly braces. Since we put all of our code inside the if hasOwnProperty block it makes any braces for the for statement unnecessary.

Essentially it's equivalent to:

for(var property in object) {
   if(object.hasOwnProperty(property)) {
     ...
   } else {
      continue;
   }
}
CD Sanchez
Thanks - this definitely helps a lot. Wasn't aware that you could structure the code in this manner!
Vivin Paliath
+1, I like this a lot and I think I'm going to start using it! (It feels a bit like Python's list comprehensions and generators, actually, though I haven't done any programming in that language)
Platinum Azure
+2  A: 

Syntacticly I'd prefer something like this

function own(obj) {
  var ownprops = {};
  for (var prop in obj) 
    if (obj.hasOwnProperty(prop)) ownprops[prop] = 1;

  return ownprops;
}

for (var property in own(object)) {
 //code
}

Looks nice, but it entails two loops over the same object, not pretty performance wise.

The other way to do it is functionaly

function foreach(obj, func, thisp) {
  for (var prop in obj)
    if (obj.hasOwnProperty(prop)) func.call(thisp, obj[prop], prop);
}

foreach(object, function(val, key) {
  //code
});

Only one loop, but a function is called for every iteration, which is not great performance wise but better than the last solution. Note that it also clobbers the value of this, but you can pass that value explicitly as the optional 3rd argument.

Just some alternatives. The way you are doing it, and the way explained by Daniel is just fine, and without performance compromises.

Also, I'd like to point out that you do not have to indent your code for every single curly brace...

MooGoo
+1 for foreach.
Anurag
Thanks! I like the `foreach` function!
Vivin Paliath
A: 

One factor depends on whether you listen to Douglas Crockford. In his book, JavaScript: The Good Parts, he lumps continue in with the bad parts.

"I have never seen a piece of code that was not improved by refactoring it to remove the continue statement." - Douglas Crockford, JavaScript: The Good Parts

As Tim Down mentioned in his comment, Crockford gives no reason in the book to explain why continue should be avoided. But on his website he says, "It tends to obscure the control flow of the function." I only mention Crockford's opinion since many consider him an authority.

Personally I don't see any problem with how you've coded your loop, especially since the continue appears right at the top where it won't easily be overlooked. Are you working with a team of developers? Do they have a good understanding of what continue does? Do you have a code conventions document that talks about how to handle deep nesting of statements?

stevelove
It's an assertion that means nothing without any reasoning to back it up.
Tim Down
You're right, and there's a suspicious lack of reasoning in the book. On his website, he only says the continue statement "tends to obscure the control flow of the function." Still, I thought it worth mentioning since many developers seem to take the words of Douglas Crockford as the Word of the Lord when it comes to JavaScript.
stevelove
Yes, I've seen `continue` clubbed together with `break`. I rarely use `break` but I've found that in some instances it actually improves readability.
Vivin Paliath
A: 

Mcconnel:

A loop with many breaks may indicate unclear thinking about the structure of the loop or its role in the surrounding code. Excessive breaks raises often indicates that the loop could be more clearly expressed as a series of loops. Use of break eliminates the possibility of treating a loop as a black box. Control a loop's exit condition with one statement to simplify your loops. 'break' forces the person reading your code to look inside to understand the loop's control, making the loop more difficult to understand.

Dijkstra:

features like break tend to sabotage the benefits of structured programming, and prevent the programmer from understanding the program as a composition of independent units

Loops with continue can be factored into this form and thus the loop may be treated as a black box. Crawford is wrong. Breaks smell, but continue is good.

further analysis: http://sites.google.com/site/dustingetz/dev/break-and-continue

Dustin Getz