Is an if with a continue a good pattern to prevent excessive nesting while iterating over properties in Javascript?

StackOverflow https://stackoverflow.com/questions/3765723

Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

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?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top